Better support of locking clauses (FOR UPDATE/SHARE) when supported
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
調査の方向性
ORM の select/query エントリポイントと with_for_update() から始め、単一の ForUpdateArg がどのように保存され、コンパイルされるかを追跡します。PostgreSQL に対して joinedload() を使用した例を再現し、生成されたロック句を期待される SQL と比較します。複数のロック句を、サポート対象のバックエンドやドキュメント化された警告を壊すことなく表現できれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Describe the use case
The Postgres docs specifically say that you should be able to have both a FOR UPDATE and a FOR SHARE in the same query:
Multiple locking clauses can be written if it is necessary to specify different locking behavior for different tables
which is often useful with join queries. In a common scenario, I'd want to take an exclusive lock on the primary row(s) being queried, and a SHARE lock on any rows that are brought in via relationships, since they're going to be read-only for the current transaction.
As far as I can tell, though, it's not actually possible to construct that in the SqlAlchemy ORM. That's because Query only supports a single ForUpdateArg, which is overwritten by with_for_update() as opposed to appending to a list. On supported platforms - or maybe attempt on all platforms and leave a user-beware dragon - we should be able to have multiple for-update clauses (see example).
I do recognize that the SqlAlchemy docs have a dragon warning for this whole area:
Using with_for_update in the context of eager loading relationships is not officially supported or recommended by SQLAlchemy and may not work with certain queries on various database backends. When with_for_update is successfully used with a query that involves joinedload(), SQLAlchemy will attempt to emit SQL that locks all involved tables.
That seems overly pessimistic, though, at least when using joinedload() (it's clearly more problematic with selectinload(), where we'd need to set the right lock clauses on the right individual selects). This feels along the lines of https://github.com/sqlalchemy/sqlalchemy/issues/5583 - is it possible to have more tailored warnings (both in code and in docs) when there are scenarios that are likely to work?
Databases / Backends / Drivers targeted
Postgres (documented valid in all versions since 9.3)
Example Use
Python:
q = (
select(A)
.filter_by(id='xyz')
.options(
joinedload(A.related_b),
joinedload(A.related_c),
)
.with_for_update(of=A)
.with_for_update(of=[B, C], read=True)
)
result = session.execute(q)
# sample continuation - reading from `related_b`, writing to the primary object:
# my_item = result.scalars().first()
# my_item.col1 = my_item.related_b.other_value + 2
# session.commit()
Expected SQL:
SELECT a.id, a.col1, a.col2, ..., b.id, b.colb1, ..., c.id, c.colc1, ...
FROM a
LEFT JOIN b ON (b.id=a.fk_to_b)
LEFT JOIN c ON (c.id=a.fk_to_c)
WHERE a.id='xyz'
FOR UPDATE OF a
FOR SHARE OF b, c;
Additional context
No response
- 主要言語
- Python
- スター
- 12.3k
- フォーク
- 1.8k
- 平均マージ
- 2日 10時間
- マージ済み PR(30日)
- 9
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
sqlalchemy/sqlalchemy のほかの issue
-
requires triage
難易度 1/5 1〜3時間 初心者へのやさしさ 85/100
sqlalchemy/sqlalchemy#13784 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
bug engine
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
sqlalchemy/sqlalchemy#13770 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
declared_attr.cascading fails to typecheck under mypy / pyright on documented usage再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンbug orm typing
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
sqlalchemy/sqlalchemy#13731 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
PostgreSQL multihost URL with bracketed IPv6 hosts raises ValueError: too many values to unpack再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンbug engine postgresql
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
sqlalchemy/sqlalchemy#13637 · コメント 6 件 ·
メンテナーはふだん 1 日以内に返信
-
asyncpg dialect raises DBAPIError, not DataError, for SQLSTATE class 22 errors対応中かも @HardMax71 が 21 日前に担当しました。 オープンbug code review in progress dialects
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
sqlalchemy/sqlalchemy#13636 · コメント 19 件 ·
メンテナーはふだん 1 日以内に返信
sqlalchemy/sqlalchemy の issue をすべて見る
似ている issue
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 80/100
glossyio/traffic-monitor#312 ·
メンテナーはふだん 1 日以内に返信
-
local devenv exampleオープンdocumentation enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
es-ude/elastic-ai.creator#1046 ·
メンテナーはふだん 3 日以内に返信
-
feature request
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
confident-ai/deepteam#306 ·
メンテナーはふだん 1 日以内に返信
-
SslLibrary crashes with unhandled OSError: port/proto not found on non-standard SSL ports対応中かも @himanchalkaushale が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
OWASP/Nettacker#1884 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信