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.

Reply via email to