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.