Polymorhic tables and __table__.columns

284 views
Skip to first unread message

Martijn Moeling

unread,
Feb 19, 2011, 12:45:15 PM2/19/11
to sqlal...@googlegroups.com
Hi,

I am running into something weird results I do not really understand. SA 0.6.6


I have a Polymorhic table setup, where I need to get the columnlist for outputting the ExtJs 4 Model.

Basically it should output    


( 'User' : { fields : [
{'field1' : 'int'},
{'field2' : 'string'},
{'field3' : 'boolean'}
]
}


to output the data to the browser in json I do

dict(Userinstance)


to get this working I have added to the BaseClass of the polymorphic setup

    def __iter__(self):
        for c in self.__table__.columns  + BaseClass.__table__.columns:
            if c.name not in ['discriminator']:
                if isinstance(c.type, DateTime):
                    value = getattr(self, c.name).strftime("%Y-%m-%d %H:%M:%S")
                else:
                    value = getattr(self, c.name)
                yield(c.name, value)

This works fine but a few things has to be taken in consideration:

Both self.__table__.columns and BaseClass.__table__.columns__ have columns defined in the BaseClass
In the above, this is no real problem since the dict keys are overwritten and they have the same value anyway.

if I do the same for generating a model:

    def ExtModel(self):
        Result = {'fields': []}
        for c in self.__table__.columns + BaseClass.__table__.columns:
            if c.name not in ['discriminator']:
                if isinstance(c.type, Unicode):
                    Result['fields'].append({'name': c.name, 'type': 'string'})
                elif isinstance(c.type, Integer):
                    Result['fields'].append({'name': c.name, 'type': 'int'})
                elif isinstance(c.type, Boolean):
                    Result['fields'].append({'name': c.name, 'type': 'boolean'})
                elif isinstance(c.type, Float):
                    Result['fields'].append({'name': c.name, 'type': 'float'})
                elif isinstance(c.type, DateTime):
                    Result['fields'].append({'name': c.name, 'type': 'date'})
        return self.__class__.__name__, Result
 
I get the Id field twice..... in the fieldlist
again they have the same value, but here it alters the result.


I need something like:
    def ExtModel(self):
        ColumnList = self.__table__.columns
        for c in BaseClass.__table__.columns:
            if c not in self.__table__.columns:
                ColumnList.append(c)
        Result = {'fields': []}
        for c in self.__table__.columns + Affiliation.__table__.columns:

   ...... etc



which gives:
    if c not in self.__table__.columns:
  File "/Library/Python/2.6/site-packages/SQLAlchemy-0.6.6-py2.6.egg/sqlalchemy/sql/expression.py", line 2064, in __contains__
    raise exc.ArgumentError("__contains__ requires a string argument")
sqlalchemy.exc.ArgumentError: __contains__ requires a string argument


One other thing i noted which is really odd....

I have multiple classes inheriting from BaseClass, which is why I have set up polymorphic inheritance in the foist place.

When I do:

alldata = s.query(BaseClass).all()
for a in alldata:
print a.ExtModel()


I notice that BaseClass.__table__.columns sometimes holds the Id in others it doesnt.

most of the classes (new project) are "empty" anyway and are no more than:

SomeClass(BaseClass):
Id = Column(Integer, ForeignKey('baseclass.Id'), primary_key=True)

SomeClass2(BaseClass):
Id = Column(Integer, ForeignKey('baseclass.Id'), primary_key=True)

That is really weird!!!!!  It solves my problem automatically on some instances but not on others and only for the Id column .......



Is there a way I can make a new ColumnList based on the self.__table__.columns and BaseClass.__tablename__ excluding the overlap. In this example I 'only' talk about the Id but in my real world there are more Columns in BaseClass


Martijn













Michael Bayer

unread,
Feb 19, 2011, 12:57:04 PM2/19/11
to sqlal...@googlegroups.com
columns.contains_column(c)



One other thing i noted which is really odd....

I have multiple classes inheriting from BaseClass, which is why I have set up polymorphic inheritance in the foist place.

When I do:

alldata = s.query(BaseClass).all()
for a in alldata:
print a.ExtModel()


I notice that BaseClass.__table__.columns sometimes holds the Id in others it doesnt.

i don't understand what "sometimes" means.   BaseClass.__table__.columns is a collection created only once.



most of the classes (new project) are "empty" anyway and are no more than:

SomeClass(BaseClass):
Id = Column(Integer, ForeignKey('baseclass.Id'), primary_key=True)

SomeClass2(BaseClass):
Id = Column(Integer, ForeignKey('baseclass.Id'), primary_key=True)

That is really weird!!!!!  It solves my problem automatically on some instances but not on others and only for the Id column .......







Is there a way I can make a new ColumnList based on the self.__table__.columns and BaseClass.__tablename__ excluding the overlap. In this example I 'only' talk about the Id but in my real world there are more Columns in BaseClass

i dunno,  [c for c in self.__table__.columns] + [c for c in BaseClass.__table__.columns if c.key not in self.__table__.columns]  ?





Martijn














--
You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To post to this group, send email to sqlal...@googlegroups.com.
To unsubscribe from this group, send email to sqlalchemy+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.

Martijn Moeling

unread,
Feb 19, 2011, 1:41:10 PM2/19/11
to sqlal...@googlegroups.com
interesting method....




One other thing i noted which is really odd....

I have multiple classes inheriting from BaseClass, which is why I have set up polymorphic inheritance in the foist place.

When I do:

alldata = s.query(BaseClass).all()
for a in alldata:
print a.ExtModel()


I notice that BaseClass.__table__.columns sometimes holds the Id in others it doesnt.

i don't understand what "sometimes" means.   BaseClass.__table__.columns is a collection created only once.

me neither, That Is why I brought it up




most of the classes (new project) are "empty" anyway and are no more than:

SomeClass(BaseClass):
Id = Column(Integer, ForeignKey('baseclass.Id'), primary_key=True)

SomeClass2(BaseClass):
Id = Column(Integer, ForeignKey('baseclass.Id'), primary_key=True)

That is really weird!!!!!  It solves my problem automatically on some instances but not on others and only for the Id column .......







Is there a way I can make a new ColumnList based on the self.__table__.columns and BaseClass.__tablename__ excluding the overlap. In this example I 'only' talk about the Id but in my real world there are more Columns in BaseClass

i dunno,  [c for c in self.__table__.columns] + [c for c in BaseClass.__table__.columns if c.key not in self.__table__.columns]  ?

yep! this works:


    def ExtModel(self):
        ColumnList = [c for c in self.__table__.columns] + [c for c in BaseClass.__table__.columns if c.key not in self.__table__.columns]
        Result = {'fields': []}
        for c in ColumnList:
            if c.name not in ['discriminator']:
                if isinstance(c.type, Unicode):
                    Result['fields'].append({'name': c.name, 'type': 'string'})
                elif isinstance(c.type, Integer):
                    Result['fields'].append({'name': c.name, 'type': 'int'})
                elif isinstance(c.type, Boolean):
                    Result['fields'].append({'name': c.name, 'type': 'boolean'})
                elif isinstance(c.type, Float):
                    Result['fields'].append({'name': c.name, 'type': 'float'})
                elif isinstance(c.type, DateTime) or isinstance(c.type, Date) or isinstance(c.type, Time) :
                    Result['fields'].append({'name': c.name, 'type': 'date'})
        return self.__class__.__name__, Result

Does the trick!







Martijn




Reply all
Reply to author
Forward
0 new messages