当前位置:  开发笔记 > 编程语言 > 正文

SQLAlchemy模型循环导入

如何解决《SQLAlchemy模型循环导入》经验,为你挑选了2个好方法。

我在同一个模块中有两个模型models.它们是1-1关系,并且已根据SQLAlchemy文档进行配置.

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')))

如果我使用字符串关系构建(即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 after both dependent classes have been defined.

如果我使用类映射,我会得到经典的循环导入错误:

Traceback (most recent call last):
File "tracking_data_runner.py", line 7, in 
from models.Tracker import Tracker
File "/.../models/Tracker.py", line 5, in 
from models.Vehicle import Vehicle
File "/.../models/Vehicle.py", line 13, in 
from models.Tracker import Tracker
ImportError: cannot import name 'Tracker'

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



1> alecxe..:

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

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

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



2> mmcclannahan..:

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

    Vehicles在我的关系中不恰当地引用.应该relationship('Vehicle'不是relationship('vehicles'

    显然,就像在AssetSettings.py(foreign_keys=Column(ForeignKey('vehicles.vehicle_id')))中那样在关系中声明FK是不合适的.我必须声明FK,然后将其传递给关系.

我的配置现在看起来像这样:

Vehicle.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'))

AssetSetting.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)

推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有