ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИРАН КЛЮЧ
след версия-1.2 за MySQL
Тази функционалност вече е вградена в SQLAlchemy само за MySQL. Отговорът на somada141 по-долу има най-доброто решение:https://stackoverflow.com/a/48373874/319066
ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИРАН КЛЮЧ
в SQL израз
Ако искате генерираният SQL действително да включва ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИРАН КЛЮЧ
, най-простият начин включва използването на @compiles
декоратор.
Кодът (с връзка от добра тема по темата в reddit ) за пример можете да намерите на github :
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Insert
@compiles(Insert)
def append_string(insert, compiler, **kw):
s = compiler.visit_insert(insert, **kw)
if 'append_string' in insert.kwargs:
return s + " " + insert.kwargs['append_string']
return s
my_connection.execute(my_table.insert(append_string = 'ON DUPLICATE KEY UPDATE foo=foo'), my_values)
Но имайте предвид, че при този подход трябва ръчно да създадете append_string. Вероятно бихте могли да промените функцията append_string, така че тя автоматично да променя низа за вмъкване във вмъкване с низ „ON DUPLICATE KEY UPDATE“, но аз няма да го направя тук поради мързел.
ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИРАН КЛЮЧ
функционалност в рамките на ORM
SQLAlchemy не предоставя интерфейс за ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИРАН КЛЮЧ
или СЛИВАНЕ
или всяка друга подобна функционалност в неговия ORM слой. Въпреки това той има session.merge()код>
функция, която може да репликира функционалността само ако въпросният ключ е първичен ключ .
session.merge(ModelObject)
първо проверява дали съществува ред със същата стойност на първичен ключ, като изпрати SELECT
заявка (или като го потърсите локално). Ако е така, той задава някъде флаг, който показва, че ModelObject вече е в базата данни и че SQLAlchemy трябва да използва UPDATE
запитване. Обърнете внимание, че сливането е доста по-сложно от това, но възпроизвежда добре функционалността с първични ключове.
Но какво ще стане, ако искате ПРИ АКТУАЛИЗИРАНЕ НА ДУБЛИКАТ КЛЮЧ
функционалност с непървичен ключ (например друг уникален ключ)? За съжаление SQLAlchemy няма такава функция. Вместо това трябва да създадете нещо, което прилича на get_or_create()
на Django . Друг отговор на StackOverflow го покрива
, и просто ще поставя модифицирана, работеща версия тук за удобство.
def get_or_create(session, model, defaults=None, **kwargs):
instance = session.query(model).filter_by(**kwargs).first()
if instance:
return instance
else:
params = dict((k, v) for k, v in kwargs.iteritems() if not isinstance(v, ClauseElement))
if defaults:
params.update(defaults)
instance = model(**params)
return instance