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.

Reply via email to