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 <[email protected]> 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 [email protected].
>>> To unsubscribe from this group, send email to
>>> [email protected].
>>> 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 [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.