- changed status to closed
mixin_column to provide more context for declarative mixins?
Issue #3149
resolved
# -*- coding: utf-8 -*-
__author__ = 'SowingSadness'
from sqlalchemy import Column, String, Integer, ForeignKey
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import has_inherited_table
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.orm import relationship
Base = declarative_base()
DBSession = scoped_session(sessionmaker())
"""@type : sqlalchemy.orm.session.Session|sqlalchemy.orm.session.SessionTransaction"""
class VehicleModel(Base):
__tablename__ = "vehicle_model"
id = Column(Integer, primary_key=True)
name = Column(String(20))
class VehicleInfo(object):
vehicle_plate_region = Column(String(5))
vehicle_plate = Column(String(20))
@declared_attr
def vehicle_model_id(cls):
return Column(Integer, ForeignKey("vehicle_model.id"))
@declared_attr
def vehicle_model(cls):
return relationship(VehicleModel, foreign_keys=[cls.vehicle_model_id])
class Vehicle(VehicleInfo, Base):
__tablename__ = 'vehicle'
id = Column(Integer, primary_key=True)
def main():
engine = create_engine('postgresql+psycopg2://postgres@localhost:5432/t1')
DBSession.configure(bind=engine)
Base.metadata.bind = engine
Base.metadata.drop_all()
Base.metadata.create_all(checkfirst=True)
vm = VehicleModel()
vehicle = Vehicle(vehicle_model=vm)
DBSession.add(vm)
DBSession.add(vehicle)
DBSession.commit()
if __name__ == '__main__':
main()
C:\Users\Kir\Documents\Work\pyramid_p27\Scripts\pythonw.exe C:/Users/Kir/Documents/Work/sqlalchemy-test/main.py
Traceback (most recent call last):
File "C:/Users/Kir/Documents/Work/sqlalchemy-test/main.py", line 58, in <module>
main()
File "C:/Users/Kir/Documents/Work/sqlalchemy-test/main.py", line 50, in main
vm = VehicleModel()
File "<string>", line 2, in __init__
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 324, in _new_state_if_none
state = self._state_constructor(instance, self)
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\util\langhelpers.py", line 725, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 158, in _state_constructor
self.dispatch.first_init(self, self.class_)
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\event\attr.py", line 260, in __call__
fn(*args, **kw)
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\mapper.py", line 2687, in _event_on_first_init
configure_mappers()
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\mapper.py", line 2583, in configure_mappers
mapper._post_configure_properties()
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\mapper.py", line 1688, in _post_configure_properties
prop.init()
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\interfaces.py", line 144, in init
self.do_init()
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\relationships.py", line 1550, in do_init
self._setup_join_conditions()
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\relationships.py", line 1624, in _setup_join_conditions
can_be_synced_fn=self._columns_are_mapped
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\relationships.py", line 1892, in __init__
self._determine_joins()
File "C:\Users\Kir\Documents\Work\pyramid_p27\lib\site-packages\sqlalchemy\orm\relationships.py", line 1996, in _determine_joins
"specify a 'primaryjoin' expression." % self.prop)
sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Vehicle.vehicle_model - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
Process finished with exit code 1
I try to use code in https://bitbucket.org/zzzeek/sqlalchemy/issue/2471/add-example-of-declared_attr-columns but result is same.
Comments (8)
-
repo owner -
repo owner - changed milestone to 1.0
- marked as enhancement
see if a new declared system to complement
#2952is feasible here, a "mixin column" that has more insight into how it is used:class VehicleInfo(object): vehicle_plate_region = Column(String(5)) vehicle_plate = Column(String(20)) @mixin_column # possibly uses __clause_element__, cls level caching, other # integrations with declarative.base def vehicle_model_id(cls): return Column(Integer, ForeignKey("vehicle_model.id")) @declared_attr def vehicle_model(cls): return relationship(VehicleModel, foreign_keys=[cls.vehicle_model_id])
-
repo owner - changed title to mixin_column to provide more context for declarative mixins?
-
repo owner - changed status to open
-
repo owner - changed status to duplicate
Duplicate of
#3150. -
repo owner thanks for pushing me on this i think
#3150will be a great addition that meets many unsolved use cases -
reporter Excelent. Because existing behavior of declared_attr is so hard and not obviously.
-
repo owner - changed status to resolved
→ <<cset c3a93b1319fa>>
- Log in to comment
when you call this:
you are invoking the VehicleInfo.vehicle_model_id method again, creating a new Column() object that is unrelated to anything else and throws it off.
Either remove it (because you have ForeignKey already):
or defer the call: