Pylons Cookbook

If you don't want to go 100% rdfalchemy this allows rdfalchemy to peacfully coexist with sqlalchemy opjects.

development.ini

Add an rdfalchemy.dburi similar to it's sqlalchemy cousin in development.ini

rdfalchemy.dburi = sleepycat://~/working/Portfolio/db_Portfolio

config/environment.py

Use the dburi from the ini by loading it in the config/environment.py file:


#after 
from sqlalchemy import engine_from_config
#add
from rdfalchemy import engine_from_config as rdf_engine_from_config

#then in 
def load_environment(global_conf, app_conf):
   
    #after
    config['pylons.g'].sa_engine = engine_from_config(config, 'sqlalchemy.')
    #add
    config['pylons.g'].ra_engine = rdf_engine_from_config(config, 'rdfalchemy.')

model/rdfModel.py

Now the rdfalchemy engine exists but not connected to your model. I do this by creating an rdfModel.py where I can create all of my model info. At the head of that file use the ra_engine placed in the config above. Something like:

from pylons import config

# this has the rdfSubject and descriptor stuff
from rdfalchemy import *
from rdfalchemy.orm import mapper

import logging

log=logging.getLogger('rdfalchemy')

# use the engine opened in load_environment
rdfSubject.db = config['pylons.g'].ra_engine

ov = Namespace("http://owl.openvest.org/2005/10/Portfolio#")
xbrli=Namespace('http://www.xbrl.org/2003/instance#')
xlink=Namespace("http://www.w3.org/1999/xlink#")
edgarns = Namespace('http://www.sec.gov/Archives/edgar')


class XbrlFile(rdfSubject):
    rdf_type = ov.XbrlFile
    schemas = rdfMultiple(ov.usesXbrlSchema, range_type=ov.XbrlSchema)
    linkbases = rdfMultiple(ov.usesXbrlLinkbase, range_type=ov.XbrlLinkbase)
    webUri = rdfSingle(ov.documentWebURI)
    
    @property
    def transitive_schemas(self):
        return [XbrlSchema(s) for s in self.db.transitive_objects(self.resUri,ov.usesXbrlSchema)]
        

class XbrlLinkbase(XbrlFile):
    rdf_type = ov.XbrlLinkbase
    
#  other model info here
    
mapper()

That's pretty simple one-step process...just create the class. In sqlalchemy you have a two-step process, create the table then create the class then run the mapper.

To make things even simpler in my model.__init__.py file in inlude:

from projectname.model.rdfModel import *

controllers

At this point you can use the classes in your rdfModel file pretty much as you would an sqlalchemy class. Dot notation should work fine including the ability to use rdfalchemy items seamlessly in Genshi or Mako templates.

Words of warning

You should be off and running with the above code but as you scale there are things to watch out for.

You are entering rdflib into a threaded environment. Some of the rdflib datastores are better suited to this and some will be much happier with a little modification.

  • Sleepycat may get a "storage locker" error after you have used it for a while. BACK UP OFTEN!
  • Mysql should be modified to use the sqlalchemy connection pooling. In it's current form it appears to hang (block) on connecing to the db in many configurations.
  • Sesame avoids the threading issues by using stateless http connections to another server. rdflib is out of the picture as a backend. http performance penalties can be significant!

rdfalchemy may add a twisted based server to connect to to avoid the threading and connection pooling issues associated with a pylons or turbogears system using rdfalchemy/rdflib for a datastore.