I have two models in the same module named models
. They are a 1-1 relationship and have been configured per the SQLAlchemy docs.
Vehicle.py
from models.AssetSetting import AssetSetting
class Vehicle(Base):
__tablename__ = 'vehicles'
vehicle_id = Column(Integer, primary_key=True)
...
settings = relationship('AssetSetting', backref=backref('asset_settings'))
AssetSetting.py
from models.Vehicle import Vehicle
class AssetSetting(Base):
__tablename__ = 'asset_settings'
asset_alert_setting_id = Column(Integer, primary_key=True, autoincrement=True)
...
vehicle = relationship('vehicles', foreign_keys=Column(ForeignKey('vehicles.vehicle_id')))
If I use the string relationship building (i.e. ForeignKey('vehicles.vehicle_id')
) I get the error:
sqlalchemy.exc.InvalidRequestError:
When initializing mapper Mapper|AssetSetting|asset_settings, expression 'vehicles' failed to locate a name ("name 'vehicles' is not defined").
If this is a class name, consider adding this relationship() to the <class 'models.AssetSetting.AssetSetting'> class after both dependent classes have been defined.
If I use the class mapping, I get the classic circular import error:
Traceback (most recent call last):
File "tracking_data_runner.py", line 7, in <module>
from models.Tracker import Tracker
File "/.../models/Tracker.py", line 5, in <module>
from models.Vehicle import Vehicle
File "/.../models/Vehicle.py", line 13, in <module>
from models.Tracker import Tracker
ImportError: cannot import name 'Tracker'
I believe I could fix this issue by putting the files in the same package but would prefer to keep them separate. Thoughts?
To avoid circular import errors, you should use string relationship building, but both of your models have to use the same Base
- the same declarative_base
instance. Instantiate your Base
once and use it when initializing both Vehicle
and AssetSetting
.
Or, you may explicitly map the table names and classes to help mapper relate your models:
Base = declarative_base(class_registry={"vehicles": Vehicle, "asset_settings": AssetSetting})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With