Skip to content

Commit cd0003a

Browse files
committed
Update Connection.execute to accept query arguments
1 parent eb8cb03 commit cd0003a

File tree

2 files changed

+51
-2
lines changed

2 files changed

+51
-2
lines changed

asyncpg/connection.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,38 @@ def transaction(self, *, isolation='read_committed', readonly=False,
112112
"""
113113
return transaction.Transaction(self, isolation, readonly, deferrable)
114114

115-
async def execute(self, script: str, *, timeout: float=None) -> str:
115+
async def execute(self, query: str, *args, timeout: float=None) -> str:
116116
"""Execute an SQL command (or commands).
117117
118+
This method can execute many SQL commands at once, when no arguments
119+
are provided.
120+
121+
Example:
122+
123+
.. code-block:: pycon
124+
125+
>>> await con.execute('''
126+
... CREATE TABLE mytab (a int);
127+
... ''')
128+
CREATE TABLE
129+
130+
>>> await con.execute('''
131+
... INSERT INTO mytab (a) VALUES ($1), ($2)
132+
... ''', 10, 20)
133+
INSERT 0 2
134+
135+
:param args: Query arguments.
136+
:param float timeout: Optional timeout value in seconds.
118137
:return str: Status of the last SQL command.
119138
"""
120-
return await self._protocol.query(script, timeout)
139+
if not args:
140+
return await self._protocol.query(query, timeout)
141+
142+
stmt = await self._get_statement(query, timeout)
143+
protocol = self._protocol
144+
_, status, _ = await protocol.bind_execute(stmt, args, '', 0,
145+
True, timeout)
146+
return status.decode()
121147

122148
async def _get_statement(self, query, timeout):
123149
cache = self._stmt_cache_max_size > 0

tests/test_execute.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,29 @@ async def test_execute_script_1(self):
2525
self.assertEqual(self.con._protocol.queries_count, 1)
2626
self.assertEqual(status, 'SELECT 10')
2727

28+
async def test_execute_script_2(self):
29+
status = await self.con.execute('''
30+
CREATE TABLE mytab (a int);
31+
''')
32+
self.assertEqual(status, 'CREATE TABLE')
33+
34+
try:
35+
status = await self.con.execute('''
36+
INSERT INTO mytab (a) VALUES ($1), ($2)
37+
''', 10, 20)
38+
self.assertEqual(status, 'INSERT 0 2')
39+
finally:
40+
await self.con.execute('DROP TABLE mytab')
41+
42+
async def test_execute_script_3(self):
43+
with self.assertRaisesRegex(asyncpg.PostgresSyntaxError,
44+
'cannot insert multiple commands'):
45+
46+
await self.con.execute('''
47+
CREATE TABLE mytab (a int);
48+
INSERT INTO mytab (a) VALUES ($1), ($2);
49+
''', 10, 20)
50+
2851
async def test_execute_script_check_transactionality(self):
2952
with self.assertRaises(asyncpg.PostgresError):
3053
await self.con.execute('''

0 commit comments

Comments
 (0)