Coverage for databases/tests/test_batch.py: 100%
160 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
1import pytest
3import prisma
4from prisma import Prisma
6from ..utils import RawQueries, DatabaseConfig
9@pytest.mark.asyncio
10async def test_base_usage(client: Prisma) -> None:
11 """Basic non context manager usage"""
12 batcher = client.batch_()
13 batcher.user.create({'name': 'Robert'})
14 batcher.user.create({'name': 'Tegan'})
15 await batcher.commit()
17 user = await client.user.find_first(where={'name': 'Robert'})
18 assert user is not None
19 assert user.name == 'Robert'
21 user = await client.user.find_first(where={'name': 'Tegan'})
22 assert user is not None
23 assert user.name == 'Tegan'
26@pytest.mark.asyncio
27async def test_context_manager(client: Prisma) -> None:
28 """Basic usage with a context manager"""
29 async with client.batch_() as batcher:
30 batcher.user.create({'name': 'Robert'})
31 batcher.user.create({'name': 'Tegan'})
33 user = await client.user.find_first(where={'name': 'Robert'})
34 assert user is not None
35 assert user.name == 'Robert'
37 user = await client.user.find_first(where={'name': 'Tegan'})
38 assert user is not None
39 assert user.name == 'Tegan'
42@pytest.mark.asyncio
43async def test_batch_error(client: Prisma) -> None:
44 """Error while committing does not commit any records"""
45 with pytest.raises(prisma.errors.UniqueViolationError) as exc:
46 batcher = client.batch_()
47 batcher.user.create({'id': 'abc', 'name': 'Robert'})
48 batcher.user.create({'id': 'abc', 'name': 'Robert 2'})
49 await batcher.commit()
51 assert exc.match(r'Unique constraint failed')
52 assert await client.user.count() == 0
55@pytest.mark.asyncio
56async def test_context_manager_error(client: Prisma) -> None:
57 """Error exiting context manager does not commit any records"""
58 with pytest.raises(prisma.errors.UniqueViolationError) as exc:
59 async with client.batch_() as batcher:
60 batcher.user.create({'id': 'abc', 'name': 'Robert'})
61 batcher.user.create({'id': 'abc', 'name': 'Robert 2'})
63 assert exc.match(r'Unique constraint failed')
64 assert await client.user.count() == 0
67@pytest.mark.asyncio
68async def test_context_manager_throws_error(client: Prisma) -> None:
69 """Context manager respects errors"""
70 with pytest.raises(RuntimeError) as exc:
71 async with client.batch_() as batcher:
72 batcher.user.create({'name': 'Robert'})
73 raise RuntimeError('Example error')
75 assert exc.match('Example error')
76 assert await client.user.count() == 0
79@pytest.mark.asyncio
80async def test_mixing_models(client: Prisma) -> None:
81 """Batching queries to multiple models works as intended"""
82 async with client.batch_() as batcher:
83 # NOTE: this is just to test functionality, the better method
84 # for acheiving this is to use nested writes with user.create
85 # client.user.create({'name': 'Robert', 'profile': {'create': {'bio': 'Robert\'s profile'}}})
86 batcher.user.create({'id': 'abc', 'name': 'Robert'})
87 batcher.profile.create(
88 {
89 'user': {'connect': {'id': 'abc'}},
90 'description': "Robert's profile",
91 'country': 'Scotland',
92 }
93 )
95 user = await client.user.find_first(where={'name': 'Robert'}, include={'profile': True})
96 assert user is not None
97 assert user.name == 'Robert'
98 assert user.profile is not None
99 assert user.profile.description == "Robert's profile"
101 assert await client.user.count() == 1
102 assert await client.profile.count() == 1
105@pytest.mark.asyncio
106async def test_mixing_actions(client: Prisma) -> None:
107 """Batching queries to different operations works as intended"""
108 async with client.batch_() as batcher:
109 batcher.user.create({'name': 'Robert'})
110 batcher.user.delete_many(where={'name': 'Robert'})
112 assert await client.user.count() == 0
115@pytest.mark.asyncio
116async def test_reusing_batcher(client: Prisma) -> None:
117 """Reusing the same batcher does not commit the same query multiple times"""
118 batcher = client.batch_()
119 batcher.user.create({'name': 'Robert'})
120 await batcher.commit()
122 assert await client.user.count() == 1
124 batcher.user.create({'name': 'Robert 2'})
125 await batcher.commit()
127 assert await client.user.count() == 2
130@pytest.mark.asyncio
131async def test_large_query(client: Prisma) -> None:
132 """Batching a lot of queries works"""
133 async with client.batch_() as batcher:
134 for i in range(1000):
135 batcher.user.create({'name': f'User {i}'})
137 assert await client.user.count() == 1000
140@pytest.mark.asyncio
141async def test_delete(client: Prisma) -> None:
142 """delete action works as suggested"""
143 user = await client.user.create({'name': 'Robert'})
144 assert await client.user.find_first(where={'id': user.id}) is not None
146 async with client.batch_() as batcher:
147 batcher.user.delete(where={'id': user.id})
149 assert await client.user.find_first(where={'id': user.id}) is None
152@pytest.mark.asyncio
153async def test_update(client: Prisma) -> None:
154 """update action works as suggested"""
155 user = await client.user.create({'name': 'Robert'})
156 assert await client.user.find_first(where={'id': user.id}) is not None
158 async with client.batch_() as batcher:
159 batcher.user.update(where={'id': user.id}, data={'name': 'Roberto'})
161 new = await client.user.find_first(where={'id': user.id})
162 assert new is not None
163 assert new.id == user.id
164 assert new.name == 'Roberto'
167@pytest.mark.asyncio
168async def test_upsert(client: Prisma) -> None:
169 """upsert action works as suggested"""
170 user_id = 'abc123'
171 assert await client.user.find_unique(where={'id': user_id}) is None
173 async with client.batch_() as batcher:
174 batcher.user.upsert(
175 where={'id': user_id},
176 data={
177 'create': {'id': user_id, 'name': 'Robert'},
178 'update': {'name': 'Robert'},
179 },
180 )
182 user = await client.user.find_unique(where={'id': user_id})
183 assert user is not None
184 assert user.id == user_id
185 assert user.name == 'Robert'
187 async with client.batch_() as batcher:
188 batcher.user.upsert(
189 where={'id': user_id},
190 data={
191 'create': {'id': user_id, 'name': 'Robert'},
192 'update': {'name': 'Roberto'},
193 },
194 )
196 user = await client.user.find_unique(where={'id': user_id})
197 assert user is not None
198 assert user.id == user_id
199 assert user.name == 'Roberto'
200 assert await client.user.count() == 1
203@pytest.mark.asyncio
204async def test_update_many(client: Prisma) -> None:
205 """update_many action works as suggested"""
206 await client.user.create({'name': 'Robert'})
207 await client.user.create({'name': 'Robert 2'})
209 async with client.batch_() as batcher:
210 batcher.user.update_many(where={'name': {'startswith': 'Robert'}}, data={'name': 'Robert'})
212 users = await client.user.find_many()
213 assert len(users) == 2
214 assert users[0].name == 'Robert'
215 assert users[1].name == 'Robert'
218@pytest.mark.asyncio
219async def test_delete_many(client: Prisma) -> None:
220 """delete_many action works as suggested"""
221 await client.user.create({'name': 'Robert'})
222 await client.user.create({'name': 'Robert 2'})
223 assert await client.user.count() == 2
225 async with client.batch_() as batcher:
226 batcher.user.delete_many(where={'name': {'startswith': 'Robert'}})
228 assert await client.user.count() == 0
231@pytest.mark.asyncio
232async def test_execute_raw(client: Prisma, raw_queries: RawQueries) -> None:
233 """execute_raw action can be used to execute raw SQL queries"""
234 post1 = await client.post.create(
235 {
236 'title': 'My first post!',
237 'published': False,
238 }
239 )
240 post2 = await client.post.create(
241 {
242 'title': 'My 2nd post.',
243 'published': False,
244 }
245 )
247 async with client.batch_() as batcher:
248 batcher.execute_raw(
249 raw_queries.update_unique_post_title,
250 post1.id,
251 )
252 batcher.execute_raw(
253 raw_queries.update_unique_post_new_title,
254 post2.id,
255 )
257 found = await client.post.find_unique(where={'id': post1.id})
258 assert found is not None
259 assert found.id == post1.id
260 assert found.title == 'My edited title'
262 found = await client.post.find_unique(where={'id': post2.id})
263 assert found is not None
264 assert found.id == post2.id
265 assert found.title == 'My new title'
268@pytest.mark.asyncio
269async def test_create_many_skip_duplicates_unsupported(
270 client: Prisma,
271 config: DatabaseConfig,
272) -> None:
273 """Cannot call create_many with skip_duplicates on databases that do not support it"""
274 if 'create_many_skip_duplicates' not in config.unsupported_features:
275 pytest.skip('The create_many skip_duplicates argument is supported by the current database')
277 with pytest.raises(prisma.errors.UnsupportedDatabaseError) as exc:
278 async with client.batch_() as batcher:
279 batcher.user.create_many([{'name': 'Robert'}], skip_duplicates=True)
281 assert exc.match(r'skip_duplicates is not supported')