Skip to content

Commit 4651c59

Browse files
committed
Add pipeline tests for nx/xx and prevent HashModel nx/xx with pipeline
- HashModel raises ValueError when nx/xx used with pipeline (not atomic) - JsonModel supports nx/xx with pipeline (JSON.SET is atomic) - Added test coverage for these behaviors
1 parent 2347533 commit 4651c59

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

aredis_om/model/model.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2639,6 +2639,11 @@ async def save(
26392639
) -> Optional["Model"]:
26402640
if nx and xx:
26412641
raise ValueError("Cannot specify both nx and xx")
2642+
if pipeline and (nx or xx):
2643+
raise ValueError(
2644+
"Cannot use nx or xx with pipeline for HashModel. "
2645+
"Use JsonModel if you need conditional saves with pipelines."
2646+
)
26422647

26432648
self.check()
26442649
db = self._get_db(pipeline)

tests/test_hash_model.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,3 +1446,24 @@ async def test_save_nx_xx_mutually_exclusive(m):
14461446

14471447
with pytest.raises(ValueError, match="Cannot specify both nx and xx"):
14481448
await member.save(nx=True, xx=True)
1449+
1450+
1451+
@py_test_mark_asyncio
1452+
async def test_save_nx_with_pipeline_raises_error(m):
1453+
"""Test that save(nx=True) with pipeline raises an error for HashModel."""
1454+
await Migrator().run()
1455+
1456+
member = m.Member(
1457+
id=4000,
1458+
first_name="Andrew",
1459+
last_name="Brookins",
1460+
email="a@example.com",
1461+
join_date=today,
1462+
age=38,
1463+
bio="Bio 1",
1464+
)
1465+
1466+
# HashModel doesn't support nx/xx with pipeline (HSET doesn't support it natively)
1467+
async with m.Member.db().pipeline(transaction=True) as pipe:
1468+
with pytest.raises(ValueError, match="Cannot use nx or xx with pipeline"):
1469+
await member.save(pipeline=pipe, nx=True)

tests/test_json_model.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1658,3 +1658,38 @@ async def test_save_nx_xx_mutually_exclusive(m, address):
16581658

16591659
with pytest.raises(ValueError, match="Cannot specify both nx and xx"):
16601660
await member.save(nx=True, xx=True)
1661+
1662+
1663+
@py_test_mark_asyncio
1664+
async def test_save_nx_with_pipeline(m, address):
1665+
"""Test that save(nx=True) works with pipeline."""
1666+
await Migrator().run()
1667+
1668+
member1 = m.Member(
1669+
first_name="Andrew",
1670+
last_name="Brookins",
1671+
email="a@example.com",
1672+
join_date=today,
1673+
age=38,
1674+
address=address,
1675+
)
1676+
member2 = m.Member(
1677+
first_name="Kim",
1678+
last_name="Brookins",
1679+
email="k@example.com",
1680+
join_date=today,
1681+
age=34,
1682+
address=address,
1683+
)
1684+
1685+
# Save both with nx=True via pipeline
1686+
async with m.Member.db().pipeline(transaction=True) as pipe:
1687+
await member1.save(pipeline=pipe, nx=True)
1688+
await member2.save(pipeline=pipe, nx=True)
1689+
await pipe.execute()
1690+
1691+
# Verify both were saved
1692+
fetched1 = await m.Member.get(member1.pk)
1693+
fetched2 = await m.Member.get(member2.pk)
1694+
assert fetched1.first_name == "Andrew"
1695+
assert fetched2.first_name == "Kim"

0 commit comments

Comments
 (0)