У меня есть запись о том, что я хочу существовать в базе данных, если ее там нет, и если она уже есть (первичный ключ существует), я хочу, чтобы поля были обновлены до текущего состояния.Это часто называют 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")
, хотя kwarg unique_key
явно не нужен (ORM должен быть в состоянии легко это выяснить) Я добавил это только потому, что SQLAlchemy имеет тенденцию работать только с первичнымключ.Например: я смотрел, будет ли Session.merge применимым, но это работает только с первичным ключом, который в данном случае является автоинкрементным идентификатором, который не очень полезен для этой цели.
Пример использования этого варианта - просто при запуске серверного приложения, которое могло обновить ожидаемые данные по умолчанию.то есть: нет проблем параллелизма для этого upsert.