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 <[email protected]> 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 <[email protected]> wrote:
>> 
>> 
>> 
>> 
>> 
>> 
>> 
>>> He Michael,
>> 
>>> You saved me again .. Thanks!
>> 
>>> On Apr 2, 2:09 am, Michael Bayer <[email protected]> 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)
>>>>>    typedefs = session.query(Type).filter(Type.atomic == False).all()
>>>>>    for typedef in typedefs:
>>>>>        tablemeta(typedef)
>>>>>    print
>>>>> "--------------------------------------------------------------------------
>>>>>  ---------"
>>>>>    for reg in register:
>>>>>        print reg
>>>>>    Base.metadata.create_all(engine) #<== ERROR
>>>>>    print"done"
>> 
>> ...
>> 
>> read more ยป
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To post to this group, send email to [email protected].
> 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.
> 

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
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.

Reply via email to