python - 使用 SqlAlchemy 代理到基于字典的集合时如何避免 IntegrityError
问题描述
使用 sqlalchemy 1.4.x,我设置了以下类:
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.orm import declarative_base, sessionmaker
from sqlalchemy.orm.collections import attribute_mapped_collection
from sqlalchemy.orm import backref, relationship
from sqlalchemy import ForeignKey, Column, Integer, Unicode
from sqlalchemy import create_engine
engine = create_engine("sqlite:///:memory:", echo=True)
Session = sessionmaker(bind=engine)
session = Session()
Base = declarative_base()
class Infra(Base):
__tablename__ = "infra"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(Unicode(200), index=True, unique=True)
protections = association_proxy(
"infra_protections",
"pscore",
creator=lambda k, v: Infra_Protection(protection=k, pscore=v),
)
class Protection(Base):
__tablename__ = "protection"
id = Column(Integer, primary_key=True, autoincrement=True)
ptype = Column(Unicode(200), index=True, unique=True)
def __init__(self, protection):
self.ptype = protection
class Infra_Protection(Base):
__tablename__ = "infraprotection"
infra_id = Column(
Integer, ForeignKey("infra.id", ondelete="CASCADE"), primary_key=True
)
protection_id = Column(
Integer, ForeignKey("protection.id", ondelete="CASCADE"), primary_key=True
)
prot = relationship("Protection")
protection = association_proxy("prot", "ptype")
infra = relationship(
Infra,
backref=backref(
"infra_protections",
collection_class=attribute_mapped_collection("protection"),
cascade="all, delete-orphan",
),
)
pscore = Column(Integer, nullable=False, unique=False, server_default="0")
现在我想添加一些Infra
对象和相关Protection
的s:
Base.metadata.create_all(engine)
i = Infra(name="Foo")
i.protections["test"] = 1
i.protections["test 2"] = 2
session.add(i)
session.commit()
# now, add another
j = Infra(name="Bar")
j.protections["test"] = 3
j.protections["test 2"] = 4
session.add(j)
session.commit() # UNIQUE constraint failed: protection.ptype
很明显,为什么违反了唯一约束,但我想知道如何修改我的关联代理设置,以合理稳健的方式避免这种情况。某种get_or_create
关于Protection
__init__
?
解决方案
处理这个问题的方法是从这里实现 UniqueObject 配方之一:https ://github.com/sqlalchemy/sqlalchemy/wiki/UniqueObject
推荐阅读
- asp.net-core-2.0 - 使用 Angular 和单页应用程序进行回发
- python - 使用多处理时不能腌制错误
- featherlight.js - 通过js手动调用Featherlight时没有固定的半透明背景
- excel - 在 Excel 中添加具有动态工作表名称的工作表作为 DATE
- google-apps-script - 如何在脚本中调整为自定义大小边距和纸张大小以将 Google 电子表格保存为 PDF?
- javascript - 为什么段落不显示?
- python - 允许用户输入两个参数
- ansible - Ansible 剧本范围的设置和任务
- c# - 从数据层访问 appsetting 而无需使用参数创建实例化
- css - 如何处理 CSS 中的级联优先级?