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.
