SQLAlchemy模型循环Imp

2024-05-14 21:22:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我在同一个模块中有两个模型,名为models。它们是1-1关系,已按照SQLAlchemy docs配置。

车辆.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'))

资产设置.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')))

如果我使用字符串关系构建(即ForeignKey('vehicles.vehicle_id')),就会得到错误:

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.

如果使用类映射,则会出现典型的循环导入错误:

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'

我相信我可以通过将文件放在同一个包中来解决这个问题,但我更希望将它们分开。思想?


Tags: namefrompyimportidsettingsmodelscolumn
3条回答

我发现我的问题有两个方面:

  1. 我在我的关系中引用Vehicles不正确。应该是relationship('Vehicle'而不是relationship('vehicles'
  2. 显然,在关系中声明FK是不合适的,就像我在AssetSettings.py中所做的那样。我必须申报FK然后把它交给这段关系。

我现在的配置如下:

车辆.py

class Vehicle(Base, IDiagnostable, IUsage, ITrackable):
    __tablename__ = 'vehicles'

    vehicle_id = Column(Integer, primary_key=True)_id = Column(Integer)
    settings = relationship('AssetSetting', backref=backref('asset_settings'))

资产设置.py

class AssetSetting(Base):
    __tablename__ = 'asset_settings'

    asset_alert_setting_id = Column(Integer, primary_key=True, autoincrement=True)
    vehicle_id = Column(ForeignKey('vehicles.vehicle_id'))

    vehicle = relationship('Vehicle', foreign_keys=vehicle_id)

为了避免循环导入错误,应该使用字符串关系构建,但是两个模型必须使用相同的Base-相同的declarative_base实例。将Base实例化一次,并在初始化VehicleAssetSetting时使用它。

或者,可以显式映射表名和类,以帮助映射器关联模型:

Base = declarative_base(class_registry={"vehicles": Vehicle, "asset_settings": AssetSetting})

您的__tablename__正在引用vehicles,但您的外键正在引用vehicle.vehicle_id

相关问题 更多 >

    热门问题