MagicStack / MagicStack/asyncpg
`get_settings()` can get out of sync after a transaction with an error is rolled back
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Python
- Sterne
- 8.1k
- Forks
- 468
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
- asyncpg version: 0.30.0
- PostgreSQL version: 17.2
- Do you use a PostgreSQL SaaS? If so, which? Can you reproduce
the issue with a local PostgreSQL install?: No - Python version: 3.12.2
- Platform: Linux
- Do you use pgbouncer?: No
- Did you install asyncpg with pip?: Yes
- If you built asyncpg locally, which version of Cython did you use?:
- Can the issue be reproduced under both asyncio and
uvloop?: Only checked asyncio but it doesn't seem likely to matter
#!/usr/bin/env python3
import asyncio
import asyncpg
async def _check_encoding(con):
current_encoding = (await con.fetch(
"select current_setting('client_encoding')")
)[0]['current_setting']
print(current_encoding)
print(con.get_settings().client_encoding)
async def test(dsn):
con = await asyncpg.connect(dsn)
print("Orig")
await _check_encoding(con)
tran = con.transaction()
await tran.start()
await con.execute("set client_encoding to 'latin1'")
print("In transaction:")
await _check_encoding(con)
try:
await con.fetch("select 1 + 'a'")
except Exception:
pass
await tran.rollback()
print("After rollback:")
await _check_encoding(con)
res = await con.fetch('select $1::text', '💩')
print(res)
asyncio.run(test(
'postgres:///main?user=edgedb&port=5656&host=localhost'
))
In a transaction, if I set client_encoding to something, and then the transaction has an error and is rolled back, the client_encoding that get_settings() returns is never reverted.
If the transaction is rolled back without an error occuring, the right thing happens.
Output:
Orig
UTF8
UTF_8
In transaction:
LATIN1
LATIN1
After rollback:
UTF8
LATIN1
Traceback (most recent call last):
File "asyncpg/protocol/prepared_stmt.pyx", line 175, in asyncpg.protocol.protocol.PreparedStatementState._encode_bind_msg
File "asyncpg/protocol/codecs/base.pyx", line 227, in asyncpg.protocol.protocol.Codec.encode
File "asyncpg/protocol/codecs/base.pyx", line 129, in asyncpg.protocol.protocol.Codec.encode_scalar
File "asyncpg/pgproto/./codecs/text.pyx", line 29, in asyncpg.pgproto.pgproto.text_encode
File "asyncpg/pgproto/./codecs/text.pyx", line 17, in asyncpg.pgproto.pgproto.as_pg_string_and_size
UnicodeEncodeError: 'latin-1' codec can't encode character '\U0001f4a9' in position 0: ordinal not in range(256)
I would expect
After rollback:
UTF8
UTF8
and no encoding error.
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit dem bereitgestellten Python-Reproducer und konzentriere dich auf den Transaktions-Rollback-Pfad und den Einstiegspunkt get_settings() der Verbindung. Bestätige den Unterschied zwischen einem Rollback nach einem Transaktionsfehler und einem sauberen Rollback, und verfolge anschließend, wie der client_encoding-Zustand aktualisiert wird; abgeschlossen ist die Aufgabe, wenn get_settings() nach dem Rollback UTF8 meldet und die anschließende Abfrage mit Textparameter erfolgreich ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- postgresql, python
- Bereich
- backend, databases
- Issue-Typ
- Bug
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Aktivitätsstatus
- Veraltet
- Klarheit
- Größtenteils klar
- Anfängerfreundlichkeit
- 42/100