UPDATE the query updates all the data inside the entity
DTPlayer opened this issue · 2 comments
Describe the bug
When sending .save() (inside any context) UPDATE query updates all data inside the selected entity, not just those specified.
To Reproduce
An example of a model for interaction:
class User(Model):
id = fields.BigIntField(pk=True)
first_name = fields.CharField(max_length=255)
balance = fields.FloatField(default=0)
is_admin = fields.BooleanField(default=False)
referral = fields.ForeignKeyField('models.User', null=True)
referral_percent = fields.IntField(default=5)
And we are trying to update the user's balance:
user = await User.get(id=1) # an example of getting an entity
user.balance = 1200
await user.save()
And inside the logs we see the UPDATE of all data (even those that we have not touched)
tortoise.db_client - DEBUG - UPDATE "user" SET "first_name"=?,"balance"=?,"is_admin"=?,"referral_percent"=?,"referral_id"=? WHERE "id"=?: ['test', 1200.0, 1, 5, None, 1] - /home/codespace/.local/lib/python3.12/site-packages/tortoise/backends/sqlite/client.py:139
Expected behavior
Expected to see a format request:
tortoise.db_client - DEBUG - UPDATE "user" SET "balance"=? WHERE "id"=?: [1200.0, 1] - /home/codespace/.local/lib/python3.12/site-packages/tortoise/backends/sqlite/client.py:139
Additional context
This problem can be critical in a situation where the task is to overwrite 2-3 fields in a table without waiting, and we want (from another thread) to change the data inside this table for the same entity, which causes an UPDATE once a second.
The solution to the problem at the moment is to write a direct SQL query inside in_transaction.
user_id = 1
amount = 1200
# user = await User.get(id=user_id)
# user.balance = amount
# await user.save()
async with in_transaction() as conn:
await conn.execute_query('UPDATE users SET balance = ? WHERE id = ?', [amount, user_id])
And get this in log:
aiosqlite - DEBUG - operation functools.partial(<bound method Connection._execute_fetchall of <Connection(Thread-1, started 133812847179520)>>, 'UPDATE "user" SET "balance" = ? WHERE "id" = ?', [1200.0, 1]) completed - /home/codespace/.local/lib/python3.12/site-packages/aiosqlite/core.py:103
It has been tested on: sqlite, postgres