2015-12-22 5 views
11

Ho due modelli nello stesso modulo denominato models. Sono una relazione 1-1 e sono stati configurati per lo SQLAlchemy docs.Importazione circolare modello 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'))) 

Se uso il rapporto costruzione stringa (ad esempio ForeignKey('vehicles.vehicle_id')) ottengo l'errore:

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. 

Se uso la mappatura di classe, ottengo il classico errore di importazione circolare:

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' 

credo che potrei risolvere questo problema, mettendo i file nello stesso pacchetto, ma preferirei tenerli separati. Pensieri?

risposta

8

ho scoperto il mio problema era duplice:

  1. stavo Referencing Vehicles impropriamente nel mio relazione. Dovrebbe essere non relationship('Vehicle'relationship('vehicles'
  2. A quanto pare è improprio dichiarare la FK all'interno della relazione come ho fatto in AssetSettings.py (foreign_keys=Column(ForeignKey('vehicles.vehicle_id'))). Dovevo dichiarare l'FK e poi passarlo alla relazione.

mie configurazioni di simile a questa società:

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

tuo __tablename__ fa riferimento vehicles ma la vostra chiave esterna fa riferimento vehicle.vehicle_id

+0

dispiace che è stato un errore di copia/incolla sul mio parte quando si scrive la domanda. – mam8cc

8

Per evitare errori circolari di importazione, si dovrebbe usare rapporto stringa costruzione, ma entrambi i vostri modelli devono utilizzare lo stesso Base - il stessa istanza declarative_base. Crea un'istantanea del tuo Base una volta e usalo durante l'inizializzazione di entrambi gli Vehicle e AssetSetting.

alternativa, è possibile mappare esplicitamente i nomi delle tabelle e le classi per aiutare mapper riferiscono i tuoi modelli:

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