2016-02-29 111 views
0

我有一個加入繼承組模型。SQLAlchemy的密新預期映射的實體實施了

class Asset(db.Model): 
    __tablename__ = 'assets' 

    asset_id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    asset_type_id = db.Column(db.ForeignKey('asset_types.asset_type_id')) 
    ... 

    __mapper_args__ = { 
     'polymorphic_on': asset_type_id 
    } 



class Vehicle(Asset): 
    __tablename__ = 'vehicles' 

    asset_id = db.Column(db.ForeignKey('assets.asset_id'), primary_key=True) 
    ... 
    ... 
    __mapper_args__ = { 
     'polymorphic_identity':2 
    } 

我想將Vehicle混入具有自引用方法的類中。像這樣:

from library.models import Vehicle as EsdbVehicle 

class Vehicle(EsdbVehicle): 

def update_usage(self, db_session, odometer): 
     self.odometer = odometer 
     db_session.commit() 

當我查詢EsdbVehicle模型vehicles = db_session.query(EsdbVehicle).all()我得到115個結果,這符合我的DB。但是,當我查詢實施車輛時,我得到0結果。我錯過了什麼?

回答

1

如果不設置數據庫連接並運行代碼,我無法100%確定,但是我的直覺告訴我這不是按預期工作,因爲它看起來像SQLAlchemy一樣,正在嘗試執行表繼承(但是既然你不是和類定義是不完整的SQLAlchemy是混淆),當你真正想要的是一個mixin。

我會嘗試更多的東西是這樣的:

class Vehicle(Asset): 
    # stuff... 
    __mapper_args__ = { 
     'polymorphic_on': 'vehicle_subtype', 
     'polymorphic_identity': 'base_vehicle' 
    } 

class UsageMixin(object): 

    def update_usage(self, *args): 
     # stuff... 
     pass 


class VehiclesThatUpdate(Vehicle, UsageMixin): 

    __mapper_args__ = { 
     'polymorphic_identity': 'updating_vehicles' 
    } 

之所以應該工作是因爲每次你擴展的ORM映射類,你基本上是告訴SQLAlchemy的要執行某種表繼承。在這種情況下,你可以逃脫只是增加一個類型(STI),因爲您不添加屬性(列)你只是添加功能。

如果這個不奏效(或不完整),只需添加一個評論,我會調整。

編輯:另一種思考。你可以做的另一件事是將繼承全部跳過,只編寫在Vehicle類上運行的函數。他們不需要成爲必要的方法。我經常這樣做,以避免我的實際SQL模型和類/方法結構之間的額外耦合。

您使用ORM的越多,您開始意識到的越多,使用的次數越少,的功能越好。

+0

看來,我不能混入一張表,只有列,基於文檔:http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/mixins.html 可悲的是我試圖重構一些不好的選擇,希望能夠聰明地使用mixin。看起來我可能必須以另一種方式做到這一點。我會將你的答案標記爲已接受。 – mam8cc

+1

是的,這是正確的,列和功能混合是唯一能在SQLAlchemy理解繼承映射的範圍內工作的東西。很高興有幫助。如果你重構ORM代碼,通常可以寫一個全新的模型,然後在重構調用者之前遷移數據並使用接口快速修補新模型。原因是與ORM代碼,你基本上是一次重構兩件事情,架構和對象模型。 –