2015-12-22 13 views
11

Ich habe zwei Modelle im selben Modul mit dem Namen models. Sie sind eine 1-1-Beziehung und wurden pro SQLAlchemy docs konfiguriert.SQLAlchemy Model Circular Import

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

Wenn ich die Zeichenfolge den Aufbau von Beziehungen (dh ForeignKey('vehicles.vehicle_id')) verwenden erhalte ich die Fehlermeldung:

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. 

Wenn ich die Klassenzuordnung verwenden, erhalte ich die klassischen Rundimportfehler:

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' 

Ich glaube, ich könnte dieses Problem beheben, indem Sie die Dateien in dem gleichen Paket setzen, aber würde es vorziehen, sie getrennt zu halten. Gedanken?

Antwort

8

ich mein Problem war zweifach entdeckt:

  1. Ich war Vehicles unsachgemäß Referenzierung in meinem Beziehung. Es sollte relationship('Vehicle' nicht relationship('vehicles'
  2. Offenbar sei es ist falsch, die FK in der Beziehung zu erklären, wie ich in tat AssetSettings.py (foreign_keys=Column(ForeignKey('vehicles.vehicle_id'))). Ich musste den FK deklarieren und ihn dann in die Beziehung eingeben.

Meine Konfigurationen wie folgt aussehen jetzt:

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

Ihre __tablename__ verweist vehicles aber Ihre Fremdschlüssel verweist vehicle.vehicle_id

+0

Sorry, dass ein copy/paste Fehler war auf dem Teil beim Schreiben der Frage. – mam8cc

8

Kreisimportfehler zu vermeiden, sollten Sie String Beziehung aufzubauen, aber Ihre beiden Modelle verwenden haben die gleiche Base verwenden - die gleiche declarative_base Instanz. Instanziieren Sie Ihre Base einmal und verwenden Sie es bei der Initialisierung sowohl Vehicle und AssetSetting.

Oder Sie explizit die Tabellennamen und Klassen abbilden Mapper beziehen Ihre Modelle zu helfen:

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