2015-12-22 23 views
11

同じモジュールに2つのモデルがあります。modelsです。それらは1-1の関係であり、SQLAlchemy docsごとに構成されています。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 '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' 

私は同じパッケージ内のファイルを置くことによってこの問題を解決する可能性が信じているが、それらを分離しておくことを好むだろう:私はクラスのマッピングを使用する場合は、私は古典的な円形インポートエラーが発生します。思考?

答えて

8

私は私の問題を発見した2倍であった:私は不適切な私にVehiclesを参照して

  1. 関係。それはrelationship('Vehicle'ないrelationship('vehicles'
  2. どうやら私がAssetSettings.pyforeign_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) 
2

あなた__tablename__vehiclesを参照しているが、外部キーは、円形のインポートエラーを回避するためにvehicle.vehicle_id

+0

申し訳ありませんがそれは私の上のコピー/貼り付けエラーでした質問を書くときには – mam8cc

8

を参照しているあなた、あなたはを構築文字列の関係を使用する必要がありますが、あなたのモデルの両方がBase同じを使用する必要があります - 同じdeclarative_baseインスタンス。 Baseを一度インスタンス化し、VehicleAssetSettingの両方を初期化するときに使用してください。

それとも、あなたは明示的マッパーを支援するために、テーブル名とクラスをマッピングすることができるモデルを関連付ける:

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