SQLAlchemy Mixin预期的映射实体得到了实现

时间:2016-02-29 15:10:04

标签: python 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个结果,这与我的数据库匹配。但是当我查询实施车辆时,我得到0结果。我错过了什么?

1 个答案:

答案 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的次数越多,您开始意识到通常使用 less 的功能会更好。