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 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 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.