abstractconcretebase doesn't correctly handle setting up "mixin" columns via name vs. attribute name
Issue #3480
resolved
without the "key" workarounds uncommented, this fails:
from sqlalchemy.ext.declarative import declarative_base, AbstractConcreteBase
from sqlalchemy.ext.declarative.api import declared_attr
from sqlalchemy.orm.mapper import configure_mappers
from sqlalchemy.orm.session import Session
from sqlalchemy.sql.schema import Column, ForeignKey
from sqlalchemy.sql.sqltypes import Date, String, Integer
Base = declarative_base()
class Company(Base):
__tablename__ = 'companies'
id = Column(Integer, primary_key=True)
class Document(object):
date = Column(Date)
documentType = Column('documenttype', String) #, key="documentType")
class ContactDocument(AbstractConcreteBase, Base, Document):
contactPersonName = Column('contactpersonname', String) #, key="contactPersonName")
salesPersonName = Column(String)
sendMethod = Column('sendmethod', String) #, key="sendMethod")
@declared_attr
def company_id(self):
return Column(ForeignKey('companies.id'))
class Offer(ContactDocument):
__tablename__ = 'offers'
id = Column(Integer, primary_key=True)
class SalesOrder(ContactDocument):
__tablename__ = 'orders'
id = Column(Integer, primary_key=True)
configure_mappers()
session = Session()
query = session.query(ContactDocument)
print(query)
#!
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 627, in __init__
self._configure_properties()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 1284, in _configure_properties
self._configure_property(key, prop, False)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 1525, in _configure_property
prop = self._property_from_column(key, prop)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 1679, in _property_from_column
"attribute." % (key, self, c))
sqlalchemy.exc.ArgumentError: When configuring property 'documentType' on Mapper|ContactDocument|pjoin, column 'documenttype' is not represented in the mapper's table. Use the `column_property()` function to force this column to be mapped as a read-only attribute.
Comments (6)
-
reporter -
reporter - changed title to abstractconcretebase doesn't correctly handle setting up "mixin" columns via name vs. attribute name
-
reporter - changed status to resolved
- Fixed bug in :class:
.AbstractConcreteBase
extension where a column setup on the ABC base which had a different attribute name vs. column name would not be correctly mapped on the final base class. The failure on 0.9 would be silent whereas on 1.0 it raised an ArgumentError, so may not have been noticed prior to 1.0. fixes#3480
→ <<cset b68c9ac93eea>>
-
The problem isn't really new. I asked about it last year: https://groups.google.com/forum/#!topic/sqlalchemy/azTpdSwzNUU
From your response I assumed this was just an SQLAlchemy limitation and not a bug.
-
reporter well it wasn't :) ive refactored declarative a lot for 1.0 to make this kind of thing more flexible.
-
Well, thank you for fixing it :)
- Log in to comment
not strictly a regression. 0.9 is broken as well, the column is still mapped incorrectly:
output:
whereas with key:
we get the expected:
the bug is in all versions and is based on the fact that the base ABC is mapped to "pjoin", but no step is performed to go through the "properties" of what is to be mapped on the base and refer them from pjoin.