Skip to content

Commit c266796

Browse files
committed
allow setting statement name in set_type_codec
This is necessary when using PgBouncer because otherwise the default simplistically-generated statement names can fight with other programs using asyncpg due to PgBouncer sharing the same underlying PostgreSQL connection and thus the prepared statement names. [Supposedly asyncpg can be made to use an unnamed statement here by turning the cache off][0], but I can't for the life of me figure out how to do that when using asyncpg through SQLAlchemy; I observe that setting `prepared_statement_cache_size` to `0` as described [here][1] doesn't cause `use_cache` to be `False`. Anyway, that's not really asyncpg's problem. I think this functionality should probably be provided either way since it'd be kinda weird to only allow configuring the names of *some* prepared statements. [0]: https://github.com/MagicStack/asyncpg/blob/1aab2094d82104d5eee2cffcfd0c7e7347d4c5b8/asyncpg/connection.py#L415-L424 [1]: https://docs.sqlalchemy.org/en/20/dialects/postgresql.html#prepared-statement-cache
1 parent 1aab209 commit c266796

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

asyncpg/connection.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ async def _introspect_types(self, typeoids, timeout):
534534

535535
return result
536536

537-
async def _introspect_type(self, typename, schema):
537+
async def _introspect_type(self, typename, schema, *, name=None):
538538
if (
539539
schema == 'pg_catalog'
540540
and typename.lower() in protocol.BUILTIN_TYPE_NAME_MAP
@@ -546,6 +546,7 @@ async def _introspect_type(self, typename, schema):
546546
limit=0,
547547
timeout=None,
548548
ignore_custom_codec=True,
549+
name=name,
549550
)
550551
else:
551552
rows = await self._execute(
@@ -554,6 +555,7 @@ async def _introspect_type(self, typename, schema):
554555
limit=1,
555556
timeout=None,
556557
ignore_custom_codec=True,
558+
name=name,
557559
)
558560

559561
if not rows:
@@ -1215,7 +1217,7 @@ async def __anext__(self):
12151217

12161218
async def set_type_codec(self, typename, *,
12171219
schema='public', encoder, decoder,
1218-
format='text'):
1220+
format='text', name=None):
12191221
"""Set an encoder/decoder pair for the specified data type.
12201222
12211223
:param typename:
@@ -1336,7 +1338,7 @@ async def set_type_codec(self, typename, *,
13361338
"""
13371339
self._check_open()
13381340
settings = self._protocol.get_settings()
1339-
typeinfo = await self._introspect_type(typename, schema)
1341+
typeinfo = await self._introspect_type(typename, schema, name)
13401342
full_typeinfos = []
13411343
if introspection.is_scalar_type(typeinfo):
13421344
kind = 'scalar'
@@ -1788,7 +1790,8 @@ async def _execute(
17881790
*,
17891791
return_status=False,
17901792
ignore_custom_codec=False,
1791-
record_class=None
1793+
record_class=None,
1794+
name=None,
17921795
):
17931796
with self._stmt_exclusive_section:
17941797
result, _ = await self.__execute(
@@ -1799,6 +1802,7 @@ async def _execute(
17991802
return_status=return_status,
18001803
record_class=record_class,
18011804
ignore_custom_codec=ignore_custom_codec,
1805+
name=name,
18021806
)
18031807
return result
18041808

@@ -1868,7 +1872,8 @@ async def __execute(
18681872
*,
18691873
return_status=False,
18701874
ignore_custom_codec=False,
1871-
record_class=None
1875+
record_class=None,
1876+
name=None,
18721877
):
18731878
executor = lambda stmt, timeout: self._protocol.bind_execute(
18741879
state=stmt,
@@ -1887,6 +1892,7 @@ async def __execute(
18871892
timeout,
18881893
record_class=record_class,
18891894
ignore_custom_codec=ignore_custom_codec,
1895+
name=name,
18901896
)
18911897
else:
18921898
result, stmt = await self._do_execute(
@@ -1895,6 +1901,7 @@ async def __execute(
18951901
timeout,
18961902
record_class=record_class,
18971903
ignore_custom_codec=ignore_custom_codec,
1904+
name=name,
18981905
)
18991906
return result, stmt
19001907

@@ -1919,14 +1926,16 @@ async def _do_execute(
19191926
retry=True,
19201927
*,
19211928
ignore_custom_codec=False,
1922-
record_class=None
1929+
record_class=None,
1930+
name=None,
19231931
):
19241932
if timeout is None:
19251933
stmt = await self._get_statement(
19261934
query,
19271935
None,
19281936
record_class=record_class,
19291937
ignore_custom_codec=ignore_custom_codec,
1938+
named=True if name is None else name,
19301939
)
19311940
else:
19321941
before = time.monotonic()
@@ -1935,6 +1944,7 @@ async def _do_execute(
19351944
timeout,
19361945
record_class=record_class,
19371946
ignore_custom_codec=ignore_custom_codec,
1947+
named=True if name is None else name,
19381948
)
19391949
after = time.monotonic()
19401950
timeout -= after - before

0 commit comments

Comments
 (0)