Jani,
Thanks for your reply - you explained it much more concisely than I did. :)
Good to have it confirmed that update_or_create() doesn't quite do what I
needed - I was confused as to whether it would or not.
Thanks for taking the time to do that function, that looks ideal. I'll test
it out.
On Friday, 6 November 2015 12:52:11 UTC, Jani Tiainen wrote:
>
> Your problem lies on the way Django actually carries out create or update.
>
> As name suggest, create or update does either one. But that's what you
> don't want - you want conditional update.
>
> Only update if certain fields have been changed. Well this can be done few
> ways.
>
> So you want to do
> "update_only_if_at_least_one_of_default_fields_changed_or_create"
>
> Operation is simple, if object is not found, create new one using defaults
> if found, pull values as a dict, compare against
> default values and if at least one differs do an update. Otherwise don't
> do anything.
>
> So basically code would look something like this:
>
> update_if_changed_or_create(**kwargs):
> defaults = kwargs.pop('defaults', None)
>
> qs = MyModel.objects.filter(**kwargs)
>
> if not qs:
> obj = MyModel(**kwargs).save()
> return obj, True # Created object
> else if len(qs) == 1:
> obj = qs[0]
> changed = False
> for k, v in defaults:
> if getattr(obj, k) != v:
> changed = True
> setattr(obj, k, v)
> if changed:
> obj.save()
> return obj, False # Updated object
> else:
> # Multiple objects...
>
> return obj, None # No change.
>
>
> On 06.11.2015 14:08, Yunti wrote:
>
> Carsten ,
>
> Thanks for your reply,
>
> A note about the last statement: If a Supplier object has the same
> unique_id, and all
> other fields (in `defaults`) are the same as well, logically there is no
> difference
> between updating and not updating – the result is the same.
>
> The entry in the database is the same - apart from the last_updated flag
> if it's not rewritten over the top of it. This means I can check for new
> data often and be alerted when there is an actual update (i.e. a change to
> the data). If it rewrites the data everytime it checks then I have no idea
> when data was actually updated.
>
> Have you checked? How?
> In your create_or_update_if_diff() you seem to try to re-invent
> update_or_create(), but
> have you actually examined the results of the
>
> supplier, created = Supplier.objects.update_or_create(...)
>
> call?
>
> I checked by seeing that the last_updated field in the database was
> updated everytime. (I suppose the issue could be with how that field gets
> reset to the next time it's run- I didn't eliminate that possibility.)
>
> Yes I was worried that I might be recreating (a poor version) of
> update_or_create() but it didn't seem to have the option where it wouldn't
> write to the database if there was no change to the data.
> Can it do this? And how would I verify when an item has been updated or
> created (or neither) - could I output to the console?
>
> If it can how do I call it so it checks against all fields (unique_id and
> defaults) and updates using the defaults if it finds a difference (and
> creates if it doesn't find a unique_id)?
>
> I'm still not sure if this is possible and how to call the function,
> particular how to pass in the remaining defaults to check against -
> **kwargs = defaults isn't right but not sure what it should be.
>
> supplier, created =
> Supplier.objects.update_or_create(unique_id=product_detail['supplierId'],
> **kwargs=defaults,
> defaults={
> 'name':
> product_detail['supplierName'],
> 'entity_name_1':
> entity_name_1,
> 'entity_name_2':
> entity_name_1,
> 'rating':
> product_detail['supplierRating']})
>
> On Thursday, 5 November 2015 20:05:39 UTC, Carsten Fuchs wrote:
>>
>> Hi Yunti, Am 05.11.2015 um 18:19 schrieb Yunti: > I have tried to use the
>> update_or_create() method assuming that it would either, create > a new
>> entry in the db if it found none or update an existing one if it found one
>> and had > differences to the defaults passed in - or wouldn't update if
>> there was no difference. A note about the last statement: If a Supplier
>> object has the same unique_id, and all other fields (in `defaults`) are the
>> same as well, logically there is no difference between updating and not
>> updating – the result is the same. > However it just seemed to recreate
>> entries each time even if there were no changes. Have you checked? How? In
>> your create_or_update_if_diff() you seem to try to re-invent
>> update_or_create(), but have you actually examined the results of the
>> supplier, created = Supplier.objects.update_or_create(...) call? > I think
>> the issue was that I wanted to: > 1) get an entry if all fields were the
>> same, update_or_create() updates an object with the given kwargs, the match
>> is not made against *all* fields (i.e. for the match the fields in
>> `defaults` are not accounted for). > 2) or create a new entry if it didn't
>> find an existing entry with the unique_id > 3) or if there was an entry
>> with the same unique_id, update that entry with remaining > fields.
>> update_or_create() should achieve this. It's hard to tell more without
>> additional information, but
>> https://docs.djangoproject.com/en/1.8/ref/models/querysets/#update-or-create
>> explains the function well, including how it works. If you work through
>> this in small steps, check examples and their (intermediate) results, you
>> should be able to find what the original problem was. Best regards, Carsten
>
> -- You received this message because you are subscribed to the Google
> Groups "Django users" group. To unsubscribe from this group and stop
> receiving emails from it, send an email to
> [email protected] <javascript:>. To post to this group,
> send email to [email protected] <javascript:>. Visit this group
> at http://groups.google.com/group/django-users. To view this discussion
> on the web visit
> https://groups.google.com/d/msgid/django-users/9b529e2d-7e2b-4194-a77c-8434efe6205d%40googlegroups.com
>
> <https://groups.google.com/d/msgid/django-users/9b529e2d-7e2b-4194-a77c-8434efe6205d%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> For more options, visit https://groups.google.com/d/optout.
>
>
--
You received this message because you are subscribed to the Google Groups
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-users/889c6480-98b3-415d-af92-490d11de5695%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.