On Aug 15, 2012, at 10:45 AM, Kuba Dolecki wrote:

> Hi,
> 
> We've used joined table inheritance up to this point, but performance issues 
> are making us explore single table inheritance. I'm running into a problem 
> with mapper configuration. Using SQLAlchemy 0.7.8, Flask-SQLAlchemy 0.16, and 
> Flask 0.8. Here is the inheritance: 

there are many things that are confusing about this model.

1.  I don't see any mention of __tablename__ anywhere.  Where is the table 
defined ?

2. You say this is single table inheritance, but I see each subclass has it's 
own primary key column, with a foreign key column pointing back to the 
superclass "table" (which isn't present).   This doesn't fit with single table 
inheritance at all.

3. There's a second re-definition of "polymorphic_on".   This isn't necessarily 
a mistake, as it is supported that loading a specific sub-hierarchy may have a 
different system of determining polymorphic identity - usually this applies to 
concrete schemes.  But with joined or single table inheritance it's extremely 
unusual, as the base table is what determines object identity in both of these 
cases.   If you load a collection of "community" rows, the ORM needs to decide 
from that base table alone what the subclass should be.   It won't see a 
sub-polymorphic-on unless the original query was against that subclass.

> 
> class Community(BaseModel, db.Model):
>    # Bar
> 
> class Group(Community):
>     ###
>         Group utilized joined table inheritance to extend Community
>     ###
>     id  = db.Column(db.Integer, db.ForeignKey('community.id'), 
> primary_key=True, nullable=False)
>     autocreated = db.Column(db.Boolean, nullable=False, default=False)
> 
>     @declared_attr
>         def __mapper_args__(cls):
>             name = cls._name()
>             identity = {
>                 'polymorphic_on': case([
>                     (cls.autocreated == True, "autocreated_group"),
>                     (cls.autocreated == False, "group")
>                 ]),
>                 'polymorphic_identity': name
>             }
>             return identity
> 
> class AutocreatedGroup(Group):
>     ###
>         AutocreatedGroup extends Group through joined table inheritance
>     ###
>     id = db.Column(db.Integer, db.ForeignKey('group.id'), primary_key=True, \
>         nullable=False)
>     
>     @declared_attr
>     def __mapper_args__(cls):
>         name = cls._name()
>         identity = {
>             'polymorphic_on': cls.autocreated_type,
>             'polymorphic_identity': name
>         }
>         return identity
> 
> class TopicAutocreatedGroup(AutocreatedGroup):
>     ###
>         TopicAutocreatedGroup extends AutocreatedGroup through single table 
> inheritance
>     ###
>     @declared_attr
>     def __mapper_args__(cls):
>         return {'polymorphic_identity': cls._name()}
> 
>     topic_created_from_id = db.Column(
>         db.Integer,
>         db.ForeignKey('topic.id'),
>         nullable = True
>     )
>     topic_created_from = db.relation(
>         "Topic",
>         primaryjoin="Topic.id == TopicAutocreatedGroup.topic_created_from_id",
>         backref=db.backref("topic_groups", uselist=True),
>         uselist=False, lazy='subquery'
>     )
> 
> Here is the stacktrace: 
> Traceback (most recent call last):
>   File "/srv/.env/lib/python2.6/site-packages/flask/app.py", line 1518, in 
> __call__
>     return self.wsgi_app(environ, start_response)
>   File "/srv/.env/lib/python2.6/site-packages/flask/app.py", line 1506, in 
> wsgi_app
>     response = self.make_response(self.handle_exception(e))
>   File "/srv/.env/lib/python2.6/site-packages/flask/app.py", line 1504, in 
> wsgi_app
>     response = self.full_dispatch_request()
>   File "/srv/.env/lib/python2.6/site-packages/flask/app.py", line 1264, in 
> full_dispatch_request
>     rv = self.handle_user_exception(e)
>   File "/srv/.env/lib/python2.6/site-packages/flask/app.py", line 1260, in 
> full_dispatch_request
>     rv = self.preprocess_request()
>   File "/srv/.env/lib/python2.6/site-packages/flask/app.py", line 1387, in 
> preprocess_request
>     rv = func()
>   File "/srv/franklin-api/api/helpers/login_manager.py", line 53, in 
> _load_user
>     user = User.for_auth_token(token)
>   File "/srv/franklin-api/api/models/user.py", line 584, in for_auth_token
>     user_for_token = cls.query.filter(cls.auth_token == auth_token).first()
>   File "/srv/.env/lib/python2.6/site-packages/flask_sqlalchemy.py", line 394, 
> in __get__
>     mapper = orm.class_mapper(type)
>   File "/srv/.env/lib/python2.6/site-packages/sqlalchemy/orm/util.py", line 
> 660, in class_mapper
>     mapperlib.configure_mappers()
>   File "/srv/.env/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 
> 2255, in configure_mappers
>     raise e
> InvalidRequestError: One or more mappers failed to initialize - can't proceed 
> with initialization of other mappers.  Original exception was: Class <class 
> 'api.models.autocreated_group.TopicAutocreatedGroup'> does not have a mapped 
> column named 'topic_created_from_id'
> 
> 
> It appears the Columns inside classes that inherit through single table 
> inheritance are not included in the mapper. Any idea of what may be going 
> wrong?
> 
> Thank you,
> Kuba
> 
> P.S. What should __mapper_args__ look like for AutocreatedGroup? Should 
> "topic_created_from_id" be automatically included in the 
> "excluded_properties" value? Currently, it's empty if I print it out. 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To view this discussion on the web visit 
> https://groups.google.com/d/msg/sqlalchemy/-/l3a-3tBjaf4J.
> 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