gpt4 book ai didi

python - polymorphic_on 可以在多于一列上使用吗?

转载 作者:行者123 更新时间:2023-12-01 05:01:28 25 4
gpt4 key购买 nike

我有一个表(并且不允许我更改其架构),其中包含由三个类表示的行。

ab 列中的值确定哪个类对应于一行。

if row.a == 'X': return X
elif row.b == 'Y': return Y
else: return Z

显然,__polymorhpic_on__ 没有好的专栏。有没有办法实现这个目标?

最佳答案

polymorphic_on可以是列或 SQL 表达式,因此您只需找出将返回标识值的适当表达式。

在这种情况下,表达式可以是返回标识子类的常量的 case 语句。 a == 'X' 映射到 1b == 'Y' 映射到 2,等等。该表达式不返回实例,它会生成一个用于映射最终实例的 SQL 表达式。

case(((a == 'X', 1), (b == 'Y', 2)), else_=3)

以下是此解决方案的完整可运行示例。 case 语句已修改为使用 literal_column。它更详细,但不需要每次发送 4 个绑定(bind)参数。

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session

engine = sa.create_engine('sqlite://', echo=True)
session = Session(bind=engine)
Base = declarative_base(bind=engine)


class ThreeWay(Base):
__tablename__ = 'three_way'

id = sa.Column(sa.Integer, primary_key=True)
a = sa.Column(sa.String)
b = sa.Column(sa.String)

__mapper_args__ = {
'polymorphic_on': sa.case(
(
(a == sa.literal_column("'X'"), sa.literal_column('1')),
(b == sa.literal_column("'Y'"), sa.literal_column('2'))
),
else_=sa.literal_column('3')
)
}


class X(ThreeWay):
__mapper_args__ = {
'polymorphic_identity': 1
}

def __init__(self, **kwargs):
kwargs['a'] = 'X'
super(X, self).__init__(**kwargs)


class Y(ThreeWay):
__mapper_args__ = {
'polymorphic_identity': 2
}

def __init__(self, **kwargs):
kwargs['b'] = 'Y'
super(Y, self).__init__(**kwargs)


class Z(ThreeWay):
__mapper_args__ = {
'polymorphic_identity': 3
}


Base.metadata.create_all()

session.add_all((X(), Y(), Z()))
session.commit()

print(session.query(ThreeWay).count()) # inserted 3 generic ThreeWay rows
print(session.query(Y).count()) # 1 of them is specifically a Y row

关于python - polymorphic_on 可以在多于一列上使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26041086/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com