如果数据库中不存在一条记录,我希望它被创建,如果该记录已存在(主键已存在),则将其字段更新为当前状态。这通常称为upsert。
下面这段不完整的代码片段可以实现此功能,但似乎有些笨重(特别是如果有更多列的情况下)。有没有更好/更佳的方法?
Base = declarative_base()
class Template(Base):
__tablename__ = 'templates'
id = Column(Integer, primary_key = True)
name = Column(String(80), unique = True, index = True)
template = Column(String(80), unique = True)
description = Column(String(200))
def __init__(self, Name, Template, Desc):
self.name = Name
self.template = Template
self.description = Desc
def UpsertDefaultTemplate():
sess = Session()
desired_default = Template("default", "AABBCC", "This is the default template")
try:
q = sess.query(Template).filter_by(name = desiredDefault.name)
existing_default = q.one()
except sqlalchemy.orm.exc.NoResultFound:
#default does not exist yet, so add it...
sess.add(desired_default)
else:
#default already exists. Make sure the values are what we want...
assert isinstance(existing_default, Template)
existing_default.name = desired_default.name
existing_default.template = desired_default.template
existing_default.description = desired_default.description
sess.flush()
有没有更好或更简洁的方法来完成这个任务?类似下面这样的东西就很好:
sess.upsert_this(desired_default, unique_key = "name")
虽然unique_key
参数显然是不必要的(ORM应该能够轻松地找出这一点),但我添加了它,因为SQLAlchemy倾向于仅使用主键。例如:我一直在研究是否可以使用Session.merge来实现这个目的,但这只适用于主键,在这种情况下,它是一个自增的id,对于此目的并不是非常有用。
一个简单的用例是当启动服务器应用程序时可能已经升级了其默认预期数据。即:对于此upsert,不存在并发问题。
name
字段是唯一的,为什么不能将其设为主键(在这种情况下合并会起作用)?为什么需要一个单独的主键? - abbot