Howdy, I'm trying to create a fairly generic graph structure in a database using SQLAlchemy. Basically, I'd like to create a root object of class "Element", and have everything inherit from Element. Connections between Elements are done through a generic class "Link", which is an Element itself, and points to two other elements as the source and the target of the link. In this way I'll be able to attach arbitrary elements to links, which I can't do if Link doesn't inherit from element.
Anyway, I've read the entry on better ways to do some polymorphic unions at http://groups.google.com/group/sqlalchemy/browse_thread/thread/4ef1ce9f7acbd494/98591e1a03b4bd71?lnk=gst&q=inheritance&rnum=44 An have been modeling much of my work off that, however, the model seems to fall apart when you have multiple foreign keys. Specifically, I've attached a file to this message which gets the following error: Traceback (most recent call last): File "poly.py", line 34, in <module> link_mapper.compile() File "build/bdist.cygwin-1.5.24-i686/egg/sqlalchemy/orm/mapper.py", line 219, in compile File "build/bdist.cygwin-1.5.24-i686/egg/sqlalchemy/orm/mapper.py", line 234, in _compile_all File "build/bdist.cygwin-1.5.24-i686/egg/sqlalchemy/orm/mapper.py", line 260, in _do_compile File "build/bdist.cygwin-1.5.24-i686/egg/sqlalchemy/orm/mapper.py", line 324, in _compile_inheritance File "build/bdist.cygwin-1.5.24-i686/egg/sqlalchemy/sql.py", line 109, in join File "build/bdist.cygwin-1.5.24-i686/egg/sqlalchemy/sql.py", line 2424, in __init__ File "build/bdist.cygwin-1.5.24-i686/egg/sqlalchemy/sql.py", line 2516, in _match_primaries sqlalchemy.exceptions.ArgumentError: Can't determine join between 'element' and 'link'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly. Unfortunately, when creating the mapper, I can't specify an onclause to the mapper. Any help on how I would accomplish this and get my such a structure in SQLAlchemy? Thanks! --Patrick --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---
from sqlalchemy import * from sqlalchemy.orm import * metadata = MetaData('sqlite://') element_table = Table('element', metadata, Column('id', Integer, primary_key=True, default=None), Column('type', CHAR(1)), ) link_table = Table('link', metadata, Column('id', Integer, ForeignKey('element.id'), primary_key=True), Column('source_id', Integer, ForeignKey('element.id')), Column('target_id', Integer, ForeignKey('element.id')), ) metadata.create_all() element_join = element_table.outerjoin(link_table, onclause=link_table.c.id==element_table.c.id) class Element(object): def __init__(self, **kwargs): for key, value in kwargs.iteritems(): setattr(self, key, value) def __repr__(self): return "%s(%s)" % (self.__class__.__name__, ','.join(["%s=%s" % (k, repr(v)) for k, v in self.__dict__.iteritems() if k[0] != '_'])) class Link(Element):pass element_mapper = mapper(Element, element_table, select_table=element_join, polymorphic_on=element_table.c.type, polymorphic_identity='e') element_mapper.compile() link_mapper = mapper(Link, link_table, inherits=element_mapper, polymorphic_identity='l') link_mapper.compile() sess = create_session() # objs = [Page(page_no=5), MagazinePage(page_no=6, orders='some text'), ClassifiedPage(page_no=7, orders='some other text', titles='classified titles')] # for o in objs: # sess.save(o) # sess.flush() # sess.clear() # print sess.query(Page).list() # print sess.query(MagazinePage).list() # print sess.query(ClassifiedPage).list()