Skip to content

Commit df86c2e

Browse files
authored
1079 Add batch to raw queries (#1080)
* add `batch` to `raw` queries * link to `batch` clause from `Raw` docs page
1 parent 89f1adb commit df86c2e

File tree

4 files changed

+68
-2
lines changed

4 files changed

+68
-2
lines changed

docs/src/piccolo/query_clauses/batch.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ batch
66
You can use ``batch`` clauses with the following queries:
77

88
* :ref:`Objects`
9+
* :ref:`Raw`
910
* :ref:`Select`
1011

1112
Example

docs/src/piccolo/query_types/raw.rst

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,26 @@ Should you need to, you can execute raw SQL.
77

88
.. code-block:: python
99
10-
>>> await Band.raw('select name from band')
10+
>>> await Band.raw('SELECT name FROM band')
1111
[{'name': 'Pythonistas'}]
1212
1313
It's recommended that you parameterise any values. Use curly braces ``{}`` as
1414
placeholders:
1515

1616
.. code-block:: python
1717
18-
>>> await Band.raw('select * from band where name = {}', 'Pythonistas')
18+
>>> await Band.raw('SELECT * FROM band WHERE name = {}', 'Pythonistas')
1919
[{'name': 'Pythonistas', 'manager': 1, 'popularity': 1000, 'id': 1}]
2020
2121
.. warning:: Be careful to avoid SQL injection attacks. Don't add any user submitted data into your SQL strings, unless it's parameterised.
22+
23+
24+
-------------------------------------------------------------------------------
25+
26+
Query clauses
27+
-------------
28+
29+
batch
30+
~~~~~
31+
32+
See :ref:`batch`.

piccolo/query/methods/raw.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import typing as t
44

5+
from piccolo.engine.base import BaseBatch
56
from piccolo.query.base import Query
67
from piccolo.querystring import QueryString
78

@@ -21,6 +22,18 @@ def __init__(
2122
super().__init__(table, **kwargs)
2223
self.querystring = querystring
2324

25+
async def batch(
26+
self,
27+
batch_size: t.Optional[int] = None,
28+
node: t.Optional[str] = None,
29+
**kwargs,
30+
) -> BaseBatch:
31+
if batch_size:
32+
kwargs.update(batch_size=batch_size)
33+
if node:
34+
kwargs.update(node=node)
35+
return await self.table._meta.db.batch(self, **kwargs)
36+
2437
@property
2538
def default_querystrings(self) -> t.Sequence[QueryString]:
2639
return [self.querystring]

tests/table/test_batch.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,47 @@ def test_batch(self):
9595
self.assertEqual(iterations, _iterations)
9696

9797

98+
class TestBatchRaw(DBTestCase):
99+
def _check_results(self, batch):
100+
"""
101+
Make sure the data is returned in the correct format.
102+
"""
103+
self.assertEqual(type(batch), list)
104+
if len(batch) > 0:
105+
row = batch[0]
106+
self.assertIsInstance(row, Manager)
107+
108+
async def run_batch(self, batch_size):
109+
row_count = 0
110+
iterations = 0
111+
112+
async with await Manager.raw("SELECT * FROM manager").batch(
113+
batch_size=batch_size
114+
) as batch:
115+
async for _batch in batch:
116+
self._check_results(_batch)
117+
_row_count = len(_batch)
118+
row_count += _row_count
119+
iterations += 1
120+
121+
return row_count, iterations
122+
123+
async def test_batch(self):
124+
row_count = 1000
125+
self.insert_many_rows(row_count)
126+
127+
batch_size = 10
128+
129+
_row_count, iterations = asyncio.run(
130+
self.run_batch(batch_size=batch_size), debug=True
131+
)
132+
133+
_iterations = math.ceil(row_count / batch_size)
134+
135+
self.assertEqual(_row_count, row_count)
136+
self.assertEqual(iterations, _iterations)
137+
138+
98139
@engines_only("postgres", "cockroach")
99140
class TestBatchNodeArg(TestCase):
100141
def test_batch_extra_node(self):

0 commit comments

Comments
 (0)