Skip to content

Commit 7c4e7a7

Browse files
Fix crash when using F expressions in versioned transactions (#528)
1 parent 8c16f38 commit 7c4e7a7

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
99
### Fixed
1010

1111
- cli: Configure package logger in addition to `dipdup` one.
12+
- database: Fixed crash when using F expressions inside versioned transactions.
1213
- tzkt: Fixed deserializing `EventData` model.
1314

1415
## [6.2.0] - 2022-10-12

src/dipdup/models.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,9 @@ async def _execute(self) -> int:
425425
_logger.debug('Got %s', len(models))
426426

427427
for model in models:
428-
model._set_kwargs(self.update_kwargs)
428+
for key, value in self.update_kwargs.items():
429+
setattr(model, key, value)
430+
429431
if update := ModelUpdate.from_model(model, ModelUpdateAction.UPDATE):
430432
get_pending_updates().append(update)
431433

tests/test_dipdup/test_rollback.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing import List
55

66
import pytest
7+
from tortoise.expressions import F
78

89
import demo_domains.models as domains_models
910
import demo_hic_et_nunc.models as hen_models
@@ -361,3 +362,59 @@ async def test_update_prefetch() -> None:
361362

362363
model_updates = await ModelUpdate.filter().count()
363364
assert model_updates == 3
365+
366+
367+
async def test_update_arithmetics() -> None:
368+
config = DipDupConfig(spec_version='1.2', package='demo_hic_et_nunc')
369+
config.initialize()
370+
dipdup = DipDup(config)
371+
in_transaction = dipdup._transactions.in_transaction
372+
373+
async with AsyncExitStack() as stack:
374+
await dipdup._set_up_database(stack)
375+
await dipdup._set_up_transactions(stack)
376+
await dipdup._set_up_hooks(set())
377+
await dipdup._initialize_schema()
378+
379+
# NOTE: INSERT
380+
async with in_transaction(level=1000, index='test'):
381+
creator = hen_models.Holder(address='')
382+
await creator.save()
383+
384+
for i in range(3):
385+
await hen_models.Token(
386+
creator=creator,
387+
level=i,
388+
supply=i,
389+
timestamp=i,
390+
).save()
391+
392+
supply = await hen_models.Token.filter().values_list('supply', flat=True)
393+
assert supply == [0, 1, 2]
394+
395+
model_updates = await ModelUpdate.filter().count()
396+
assert model_updates == 4
397+
398+
# NOTE: UPDATE with arithmetics
399+
async with in_transaction(level=1001, index='test'):
400+
await hen_models.Token.filter().update(supply=F('supply') * 2)
401+
402+
supply = await hen_models.Token.filter().values_list('supply', flat=True)
403+
assert supply == [0, 2, 4]
404+
405+
model_updates = await ModelUpdate.filter().count()
406+
assert model_updates == 7
407+
408+
# NOTE: Rollback UPDATE with arithmetics
409+
await HookContext.rollback(
410+
self=dipdup._ctx, # type: ignore
411+
index='test',
412+
from_level=1001,
413+
to_level=1000,
414+
)
415+
416+
supply = await hen_models.Token.filter().values_list('supply', flat=True)
417+
assert supply == [0, 1, 2]
418+
419+
model_updates = await ModelUpdate.filter().count()
420+
assert model_updates == 4

0 commit comments

Comments
 (0)