coleifer / peewee

a small, expressive orm -- supports postgresql, mysql, sqlite and cockroachdb
http://docs.peewee-orm.com/
MIT License
11.06k stars 1.37k forks source link

sql in record update #2919

Closed fruitoiz closed 1 month ago

fruitoiz commented 1 month ago

Hello, please add the ability to use SQL when updating a record. ———————— Здравствуйте, добавьте пожалуйста возможность использовать SQL в обновлении записи.

Example: Stat.update(fn.SQL("loss+1")

coleifer commented 1 month ago

Well you can already, though you need to specify which field is being updated:

Stat.update(loss=SQL('loss + 1')).sql()
#  ('UPDATE "stat" SET "loss" = loss + 1', [])

# Even better:
Stat.update(losses=SQL('losses + ?', (1,))).sql()
# ('UPDATE "stat" SET "losses" = losses + ?', [1])

If you want full control then issue your query via .execute_sql():

db.execute_sql('update stat set loss=loss+?', (1,))
fruitoiz commented 1 month ago

Unfortunately, none of the options suits me. I would like to update a record without specifying fields, do it through SQL, but pure SQL is not suitable.

coleifer commented 1 month ago

Is there a reason specifying the field doesn't work? I'd like to better understand this requirement.

fruitoiz commented 1 month ago

Hello, to perform this query:

User.update(balance=User.balance*1.01).where(User.id==1) But when I output the request to the console, I get:

UPDATE `user` SET `balance` = (`user`.`balance` * 1) WHERE (`user`.`id` = 1)
coleifer commented 1 month ago

Balance is presumably an integer field? It should be instead a DecimalField.

coleifer commented 1 month ago

Alternatively, you can tell Peewee not to apply the IntegerField conversion to the value:

User.update(balance=User.balance * Value(1.01, False)).where(User.id == 1)
# UPDATE "user" SET "balance" = ("user"."balance" * 1.01) WHERE ("user"."id" = 1)