Hi Michael, Could "cls.links.member_name == mem.name" have been the problem? "mem.name" is just a string. "cls" and "cls.links" are classes/tables (links is just an extra attribute in cls).
Regards, Lars Ce On Apr 3, 6:53 pm, Michael Bayer <mike...@zzzcomputing.com> wrote: > On Apr 3, 2011, at 11:50 AM, farcat wrote: > > > The problem seemed to be in the order of adding relationships. The > > main difference is that now i call DeclarativeMeta.__init__ before > > adding relationships. Even using a dict with relationship attributes > > as last argument to __init__ did not work.( BTW cls.links is a table/ > > class used for references to records in dynamic other tables.) > > The declarative metaclass itself receives relationship() objects and > initializes them just fine when used normally. It appears like you were > creating a relationship() passing in non-SQL expression objects (i.e. not > Column objects or similar), so an expression like "x==y" would just be False. > > > > > > > > > > > > On Apr 2, 2:59 pm, farcat <gemer...@gmail.com> wrote: > >> Hello, > > >> I get the following error: > >> _______________________________________ > >> Traceback (most recent call last): > >> File "D:\Documents\Code\Eclipse\workspace\SQLAtest\data.py", line > >> 29, in <module> > >> I1 = reg["integer"](integer = 5321) > >> File "<string>", line 4, in __init__ > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\state.py", line > >> 100, in initialize_instance > >> fn(self, instance, args, kwargs) > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py", line > >> 2413, in _event_on_init > >> instrumenting_mapper.compile() > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py", line > >> 807, in compile > >> mapper._post_configure_properties() > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\mapper.py", line > >> 837, in _post_configure_properties > >> prop.init() > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\interfaces.py", > >> line 475, in init > >> self.do_init() > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\properties.py", > >> line 900, in do_init > >> self._determine_synchronize_pairs() > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\properties.py", > >> line 1157, in _determine_synchronize_pairs > >> eq_pairs = self._sync_pairs_from_join(self.primaryjoin, True) > >> File "C:\python27\lib\site-packages\sqlalchemy\orm\properties.py", > >> line 1141, in _sync_pairs_from_join > >> self > >> sqlalchemy.exc.ArgumentError: Could not determine relationship > >> direction for primaryjoin condition 'False AND False', on relationship > >> F_Address_links.number. Ensure that the referencing Column objects > >> have a ForeignKey present, or are otherwise part of a > >> ForeignKeyConstraint on their parent Table, or specify the > >> foreign_keys parameter to this relationship. > >> ____________________________________________ > > >> Strange thing is that the line "I1 = reg["integer"](integer = 5321)" > >> is the first object/record I create and it works when I do not create > >> any other classes. Also the class/table "F_Address_links" in the error > >> message exists but no objects/records have been created yet. For > >> example I do not understand how "I1 = reg["integer"](integer = 5321)" > >> leads to a call to a method that does anything with "F_Address_links" > >> or related class/table "F_Address". > > >> Please help ... It might be related to the ForeignKey in the code I > >> showed earlier in this thread, but I don't see how. > > >> On Apr 2, 11:56 am, farcat <gemer...@gmail.com> wrote: > > >>> He Michael, > > >>> You saved me again .. Thanks! > > >>> On Apr 2, 2:09 am, Michael Bayer <mike...@zzzcomputing.com> wrote: > > >>>> On Apr 1, 2011, at 2:52 PM, farcat wrote: > > >>>>> Hi Michael, > > >>>>> Still stuck, I don't mixin foreign keys or relationships. When is a > >>>>> Column attached to a table in declarative? > > >>>> so you have a few things like: > > >>>>> class AtomBase(BaseBase): > >>>>> id = Column(Integer, primary_key=True) > > >>>> where AtomBase does not appear to be a declarative class. Its hard to > >>>> follow but it appears AtomBase is taking the path that mixins take in > >>>> declarative (indeed: "__new__(mcls, name, (AtomBase, Base)"). This > >>>> means "id" will be copied for each actual declarative class generated > >>>> from AtomBase. > > >>>> Later you have: > > >>>>> ForeignKey(parent.id), > > >>>> This is referencing an "id" column probably too early. In all > >>>> likelihood It isn't being linked to a table, a copy of it is. Use > >>>> ForeignKey("parent_table_name.id") instead so that the column is > >>>> evaluated as late as possible. > > >>>>> My code is: > > >>>>> import datetime > >>>>> from datatypes import * > >>>>> from accessors import member_accessor, reference_accessor > > >>>>> from sqlalchemy import * > >>>>> from sqlalchemy.orm import relationship > >>>>> from sqlalchemy.orm.session import sessionmaker > >>>>> from sqlalchemy.ext.declarative import declared_attr, DeclarativeMeta > >>>>> from sqlalchemy.types import Text, BigInteger, Float, Boolean, Date, > >>>>> Time > >>>>> #-------------------------------------------------------------------------- > >>>>> - > >>>>> engine = create_engine('sqlite:///:memory:', echo=False) > >>>>> Session = sessionmaker(bind=engine) > >>>>> register = dict() > > >>>>> #-------------------------------------------------------------------------- > >>>>> - > >>>>> class BaseBase(object): > >>>>> session = Session() > >>>>> @declared_attr > >>>>> def __tablename__(cls): return cls.__name__ > >>>>> def __init__(self, **kwargs): > >>>>> Base.__init__(self, **kwargs) > >>>>> self.session.add(self) > >>>>> print str(self) + " added to session " + str(self.session) > >>>>> def __repr__(self): > >>>>> out = "type: " + type(self).__name__ + "{" > >>>>> for name, mem in self.__dict__: > >>>>> out += name + ": " + str(mem) + ", " > >>>>> out += "}" > >>>>> return out > > >>>>> #-------------------------------------------------------------------- > >>>>> class AtomBase(BaseBase): > >>>>> id = Column(Integer, primary_key=True) > >>>>> atomic = True > >>>>> #-------------------------------------------------------------------- > >>>>> class atommeta(DeclarativeMeta): > >>>>> def __new__(mcls, name, coltype): > >>>>> return DeclarativeMeta.__new__(mcls, name, (AtomBase, Base), > >>>>> {name:Column(coltype, nullable = False)}) > >>>>> def __init__(cls, name, coltype): > >>>>> register[name] = cls > >>>>> return DeclarativeMeta.__init__(cls, name, (AtomBase, Base), > >>>>> {}) > >>>>> #-------------------------------------------------------------------------- > >>>>> - > >>>>> class BaseLink(BaseBase): > > >>>>> member_name = Column(String(64), primary_key = True) #Name of > >>>>> member of parent class > >>>>> member_table = Column(String(64), primary_key = True) #Name of > >>>>> table in which value of member resides > >>>>> member_id = Column(Integer, primary_key = True) #record > >>>>> is in member_table, with previous column enables polymorphism > >>>>> def _getitem(self): > >>>>> t = register[self.member_table] > >>>>> return self.session.query(t).filter(self.member_id == > >>>>> t.id).one() > >>>>> def _setitem(self, val): > >>>>> try: del self.item > >>>>> except AttributeError: pass > >>>>> self.member_table = val.__tablename__ > >>>>> self.member_id = val.id > >>>>> def _delitem(self): > >>>>> t = register[self.member_table] > >>>>> self.session.query(t).filter(t.id == self.member_id).delete() > >>>>> item = property(_getitem, _setitem, _delitem) > >>>>> #-------------------------------------------------------------------------- > >>>>> - > >>>>> class BaseTable(BaseBase): > > >>>>> id = Column(Integer, primary_key = True) > >>>>> created_at = Column(DateTime, default=datetime.datetime.now()) > >>>>> atomic = False > >>>>> #-------------------------------------------------------------------------- > >>>>> - > >>>>> class linkmeta(DeclarativeMeta): > >>>>> def __new__(mcls, parent): > >>>>> return DeclarativeMeta.__new__(mcls, "%s_links" % > >>>>> parent.__name__, (BaseLink, Base), > >>>>> {"parent_id": Column(Integer, > >>>>> ForeignKey(parent.id), primary_key=True)}) > >>>>> def __init__(cls, parent): > >>>>> return DeclarativeMeta.__init__(cls, "%s_links" % > >>>>> parent.__name__, (BaseLink, Base), {}) > >>>>> #-------------------------------------------------------------------------- > >>>>> - > >>>>> class tablemeta(DeclarativeMeta): > > >>>>> def __new__(mcls, typedef): > >>>>> out = DeclarativeMeta.__new__(mcls, str(typedef.name), > >>>>> (BaseTable,Base), {}) > >>>>> out.links = linkmeta(out) #<== Creates class/table enables > >>>>> links to other tables > >>>>> members = typedef.all() > >>>>> for mem in members: > >>>>> if not mem.type.name in register: > >>>>> tablemeta(mem.type) > >>>>> setattr(out, "_" + mem.name, relationship(out.links, > >>>>> uselist = > >>>>> (mem.multiplicity != "one"), > >>>>> backref = > >>>>> mem.name, > >>>>> primaryjoin = > >>>>> and_(out.links.parent_id == out.id, > > >>>>> out.links.member_name == mem.name))) > >>>>> return out > >>>>> def __init__(cls, typedef): > >>>>> register[cls.__name__] = cls > >>>>> temp = dict() > >>>>> members = typedef.all() > >>>>> for mem in members: > >>>>> if mem.reference: > >>>>> temp[mem.name] = reference_accessor(mem.name, > >>>>> register[mem.type_name], mem.multiplicity) > >>>>> else: > >>>>> temp[mem.name] = member_accessor(mem.name, > >>>>> register[mem.type_name], mem.multiplicity) > >>>>> return DeclarativeMeta.__init__(cls, typedef.name, > >>>>> (BaseTable,Base), temp) > >>>>> #-------------------------------------------------------------------------- > >>>>> - > >>>>> def createClasses(engine, session): > >>>>> print "creating classes and tables" > >>>>> atommeta("text", Text) > >>>>> atommeta("integer", BigInteger) > >>>>> atommeta("decimal", Float) > >>>>> atommeta("boolean", Boolean) > >>>>> atommeta("date", Date) > >>>>> atommeta("time", Time) > > ... > > read more » -- 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 sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.