基于Mixin列的SQLalchemy连接继承查询

2024-09-29 02:27:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个如下所示的声明类结构:

class BaseClass(Base):
      Column A
      Column B

class Mixin(object):
      Column C

class ItemA(BaseClass):
      Column D

class ItemB(Mixin, BaseClass):
      pass

class ItemC(Mixin, BaseClass):
      Column E

有没有一种方法可以使用with_polymorphic,这样我就可以在所有Items中基于Column C进行查询,而不必明确知道我有什么Item?基本上像是

^{pr2}$

假设在导入时,MixinClass的所有派生都将在声明with_polymorphic之前导入。在

编辑 请注意,我省略了联接表继承的样板,但是假设它已经正确地设置为这样做

poly_base = with_polymorphic(base = BaseClass, classes = '*')
session.query(poly_base).filter(BaseClass.a == value, ...)

按预期执行查询BaseClass中的列。关键是能够以相同的方式查询继承Mixin类的子类中的公共列。在


Tags: 声明baseobjectwithcolumnpassmixin结构
1条回答
网友
1楼 · 发布于 2024-09-29 02:27:40
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import inspect

Base = declarative_base()

class BaseClass(Base):
    __tablename__ = 'base'

    id = Column(Integer, primary_key=True)
    type = Column(String)
    a = Column(Integer)
    b = Column(Integer)
    __mapper_args__ = {"polymorphic_on": type}

class Mixin(object):
    c = Column(Integer)

class ItemA(BaseClass):
    __tablename__ = 'a'
    id = Column(ForeignKey('base.id'), primary_key=True)
    d = Column(Integer)
    __mapper_args__ = {"polymorphic_identity": 'a'}

class ItemB(Mixin, BaseClass):
    __tablename__ = 'b'
    id = Column(ForeignKey('base.id'), primary_key=True)
    __mapper_args__ = {"polymorphic_identity": 'b'}

class ItemC(Mixin, BaseClass):
    __tablename__ = 'c'
    id = Column(ForeignKey('base.id'), primary_key=True)
    e = Column(Integer)
    __mapper_args__ = {"polymorphic_identity": 'c'}

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

def magic_w_poly(base):
    insp = inspect(base)

    w_poly = []
    crit = []

    for mapper in insp.self_and_descendants:
        if "c" in mapper.c:
            w_poly.append(mapper)
            crit.append(mapper.c.c)
    w_col_c = with_polymorphic(base, w_poly)

    def comparator(value):
        return or_(
                    crit_elem == value
                    for crit_elem in crit
                )

    return w_col_c, comparator

s = Session(e)

w_col, comp = magic_w_poly(BaseClass)

print s.query(w_col).filter(comp(35))

末尾查询:

^{pr2}$

相关问题 更多 >