重複するキーの更新
MySQLのバージョン1.2以降
この機能は、SQLAlchemyforMySQLにのみ組み込まれています。以下のsomada141の回答が最善の解決策です: https://stackoverflow.com/a/48373874/319066
重複するキーの更新
SQLステートメント内
生成されたSQLに実際にONDUPLICATE KEY UPDATE
を含める場合 、最も簡単な方法は、 @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は、 ON DUPLICATE KEY UPDATE
へのインターフェースを提供していません。 またはMERGE
またはそのORMレイヤーの他の同様の機能。それでも、 session.merge()コード>
問題のキーが主キーである場合にのみ機能を複製できる関数 。
session.merge(ModelObject)
最初に、 SELECT
を送信して、同じ主キー値を持つ行が存在するかどうかを確認します クエリ(またはローカルで検索)。含まれている場合は、ModelObjectがすでにデータベースにあり、SQLAlchemyが UPDATE
を使用する必要があることを示すフラグをどこかに設定します。 クエリ。マージはこれよりもかなり複雑ですが、主キーを使用して機能を適切に複製することに注意してください。
ただし、 ON DUPLICATE KEY UPDATE
が必要な場合はどうでしょうか。 非主キー(たとえば、別の一意のキー)を使用する機能?残念ながら、SQLAlchemyにはそのような機能はありません。代わりに、Djangoの get_or_create()
に似たものを作成する必要があります 。 別の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