Re: Updating a model instance with extra checks.

2012-08-21 Thread Sebastien Flory
That was my idea too, but using this way, the pre_save / post_save signals 
wont be triggered.
It seems strange to me to be using the objects manager instead of the model 
instance directly, no?

Seb

Le mardi 21 août 2012 02:11:42 UTC+2, Thomas Orozco a écrit :
>
> As a followup to the suggestion of MyModel.objects.filter(money__gte = 
> value, pk = self.pk).update(F...)
>
> Here's an example:
>
> We have testapp/models.py:
>
> from django.db import models
> class TestModel(models.Model):
> balance =  models.IntegerField()
>
>
> >>> from django.db.models import F
> >>> TestModel.objects.create(balance = 5) #Pk will be 1 I just create one. 
> >>> import logging
> >>> l = logging.getLogger('django.db.backends')
> >>> l.setLevel(logging.DEBUG)
> >>> l.addHandler(logging.StreamHandler())
> >>> TestModel.objects.filter(balance__gte = 4, pk = 1).update(balance = 
> F('balance') - 4)
> (0.001) UPDATE "testapp_testmodel" SET "balance" = 
> "testapp_testmodel"."balance" - 4 WHERE ("testapp_testmodel"."balance" >= 4 
>  AND "testapp_testmodel"."id" = 1 ); args=(4, 4, 1)
> 1
> >>> TestModel.objects.filter(balance__gte = 4, pk = 1).update(balance = 
> F('balance') - 4)
> (0.000) UPDATE "testapp_testmodel" SET "balance" = 
> "testapp_testmodel"."balance" - 4 WHERE ("testapp_testmodel"."balance" >= 4 
>  AND "testapp_testmodel"."id" = 1 ); args=(4, 4, 1)
> 0
>
>
>
> *So this seems to generate a single SQL statement.*
> *
> *
> *I'm not totally familiar with database administration though, so as** Melvyn 
> rightly pointed out, it's always better if you can get the extra security 
> of having an SQL constraint into your dabatase and wrap your queries in a 
> transaction (as you'll probably be adding a line to the statement if the 
> withdrawal succeeds).*
> *
> *
>
> 2012/8/20 Thomas Orozco <g.orozc...@gmail.com >
>
>> A few suggestions :
>>
>> Circumvent the problem with smarter design: don't store the money on the 
>> object, make the user's money the sum of all their transactions (credit - 
>> debit). 
>> You get lesser performance, but you also get history! 
>>
>> Maybe you could try (not sure about that): 
>>
>> MyModel.objects.filter(money__gte = value, pk = self.pk).update(F...) 
>>
>> and inspect the return value (number of updated rows!). 
>> Now, you'd need to make sure django does that in a single statement. 
>>
>> If that doesn't work, I think update is the way to go anyway, but it 
>> might get a bit messy. 
>>
>> F... is an F object whose syntax I don't have off the top of my head. 
>> Le 20 août 2012 18:54, "Sebastien Flory" <sfl...@gmail.com > 
>> a écrit :
>>
>> Hi everyone,
>>>
>>> I'm looking for the proper django way to do an update of an attribute on 
>>> my model instance, but only if the attribute current value is checked 
>>> agains't a condition, in an atomic way, something like this:
>>>
>>> def use_money(self, value):
>>>   begin_transaction()
>>>   real_money = F('money')
>>>   if real_money >= value:
>>> self.money = F('money') - value
>>>  self.save()
>>>   end_transaction()
>>>
>>> I want to make sure that I avoid race condition so money never goes 
>>> below 0.
>>>
>>> Can you help me out?
>>>
>>> Thanks,
>>>
>>> Sebastien
>>>
>>> -- 
>>> You received this message because you are subscribed to the Google 
>>> Groups "Django users" group.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msg/django-users/-/hr1fBuAcX3kJ.
>>> To post to this group, send email to django...@googlegroups.com
>>> .
>>> To unsubscribe from this group, send email to 
>>> django-users...@googlegroups.com .
>>> For more options, visit this group at 
>>> http://groups.google.com/group/django-users?hl=en.
>>>
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-users/-/x8CZ3-F30PsJ.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



Updating a model instance with extra checks.

2012-08-20 Thread Sebastien Flory
Hi everyone,

I'm looking for the proper django way to do an update of an attribute on my 
model instance, but only if the attribute current value is checked agains't 
a condition, in an atomic way, something like this:

def use_money(self, value):
  begin_transaction()
  real_money = F('money')
  if real_money >= value:
self.money = F('money') - value
self.save()
  end_transaction()

I want to make sure that I avoid race condition so money never goes below 0.

Can you help me out?

Thanks,

Sebastien

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-users/-/hr1fBuAcX3kJ.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.