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