我在现场有 UniqueConstraint,但它不允许我添加多个条目(最多两个!)
from sqlalchemy import Column, Integer, String, Boolean, UniqueConstraint
class Cart(SqlAlchemyBase):
__tablename__ = 'cart'
__table_args__ = (UniqueConstraint('is_latest'), {})
sid = Column(Integer, primary_key=True)
is_latest = Column(Boolean, index=True, nullable=False)
name = Column(String)
我想支持更多条目,以便一个名称可以有两种变体:
name=foo, is_latest=True
name=foo, is_latest=False
name=bar, is_latest=True
name=bar, is_latest=False
但随后拒绝任何后续尝试写入 name=foo (或 bar)和 is_latest=True
您在这里想要实现的是类型2 缓慢变化的维度 https://en.wikipedia.org/wiki/Slowly_changing_dimension#Type_2:_add_new_row,这是一个已经被广泛讨论的话题,我鼓励你去查一下。
当我看你的桌子时,你似乎使用sid
作为代理键,但我看不到什么是自然键以及随着时间的推移会更新什么。
无论如何,有几种方法可以实现 SCD 类型 2 结果,而无需担心您的检查,但我认为最简单的方法是继续使用自然键添加记录,并且在查询时仅选择代理键最高的记录(自动递增整数),此处不需要当前唯一性,因为仅获取最新值。
有一些例子SQLAlchemy 文档中的版本控制行 https://docs.sqlalchemy.org/en/14/orm/examples.html#examples-versioned-rows,但由于网站来来去去,我将在此处放置上述方法的简化草案。
class VersionedItem(Versioned, Base):
id = Column(Integer, primary_key=True) # surrogate key
sku = Column(String, index=True) # natural key
price = Column(Integer) # the value that changes with time
@event.listens_for(Session, "before_flush")
def before_flush(session, flush_context, instances):
for instance in session.dirty:
if not (
isinstance(instance, VersionedItem)
and session.is_modified(instance)
and attributes.instance_state(instance).has_identity
):
continue
make_transient(instance) # remove db identity from instance
instance.id = None # remove surrogate key
session.add(instance) # insert instance as new record
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)