📌
SQLAlchemyとSQLServerの組み合わせでupdlock, rowlock等をかける方法
TL;DR
session.execute(
select(Table).with_hint("WITH (ROWLOCK)").where(Table.count > 0)
)
# SELECT * FROM Table WITH (ROWLOCK) WHERE count > 0
やりたいこと
SQLAlchemyではロックをかける場合普通ならwith_for_update
メソッドを用いますが、以下の例を見ての通り、SQLServerにFOR UPDATE
はないのでこの記述は無視されます。
from sqlalchemy.sql import select, table, literal_column
from sqlalchemy.dialects import mssql
tbl = table("MyTable")
stmt = select([tbl]).where(literal_column("hoge") > 0).with_for_update()
print(stmt.compile(dialect=mssql.dialect()))
# SELECT
# FROM [MyTable]
# WHERE hoge > :hoge_1
解決策
SQLServerではロックはFROM句の末尾にロックヒントという形でWITH (ROWLOCK, UDPLOCK)
などと記述します。SQLAlchemyではwith_hint
というメソッドを用いて以下のようにヒント文字列を埋め込むことができます。
from sqlalchemy.sql import select, table, literal_column
from sqlalchemy.dialects import mssql
tbl = table("MyTable")
stmt = select([tbl]).with_hint(tbl, "WITH (ROWLOCK)").where(literal_column("count") > 0)
print(stmt.compile(dialect=mssql.dialect()))
# SELECT
# FROM [MyTable] WITH (ROWLOCK)
# WHERE count > :count_1
めでたしめでたし
参考
Discussion