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)
> >    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"
>
> > Please help ....
>
> > The typedefs variables describe classes and members, and are queried
> > from normal tables
>
> > On Mar 31, 5:33 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> >> On Mar 31, 2011, at 11:29 AM, farcat wrote:
>
> >>> Hi,
>
> >>> I am getting the following error after creating a number of classes
> >>> through metaclasses:
>
> >>>  File "C:\python27\lib\site-packages\sqlalchemy\dialects\sqlite
> >>> \base.py", line 280, in visit_foreign_key_constraint
> >>>    if local_table.schema != remote_table.schema:
> >>> AttributeError: 'NoneType' object has no attribute 'schema'
>
> >>> Before I paste in any code (would need quite a lot), can anyone point
> >>> me in the right direction?
>
> >> There's a Column not attached to a Table somewhere.       Like, if you are 
> >> creating a copy of a column, giving that to a table, but then the original 
> >> is what you put in ForeignKey.
>
> >>> --
> >>> 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 
> >>> athttp://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 sqlalchemy@googlegroups.com.
> > To unsubscribe from this group, send email to 
> > sqlalchemy+unsubscr...@googlegroups.com.
> > For more options, visit this group 
> > athttp://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 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