Hello,

currently get_or_create(params) is implemented (imprecisely) this way:

try:
  self.get(params)
except DoesNotExist:
  self._create_object_from_params(params)

This creates concurrency problem, as the object might get created by another thread, after get(params) threw an exception and before _create_object_from_params has started.

Luckily Postgresql lets combine the above statements into a single structured query. This should be a performance gain as for the DB is faster to execute one than a two queries.

Consider this:

CREATE TABLE t (
  id SERIAL PRIMARY KEY,
  name VARCHAR(10) NOT NULL UNIQUE,
  comment VARCHAR(10));

And here comes the magic:

WITH
  to_be_inserted AS (SELECT 'nameD' as "name", 'comment13' as "comment"),
  just_inserted AS (
         INSERT INTO t (name, comment) SELECT * FROM to_be_inserted
                        WHERE NOT EXISTS(
                     SELECT * FROM t WHERE t.name='nameD')
         RETURNING *)
SELECT *, FALSE as "created" FROM t WHERE t.name='nameD' UNION ALL SELECT *, TRUE AS "created" FROM just_inserted;

where "to_be_inserted contains" the values for the new object ('default' parameter of get_or_create) and 'nameB' is the criterion passed to get().

Regards
  Дилян

--
You received this message because you are subscribed to the Google Groups "Django 
developers  (Contributions to Django itself)" 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 https://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/f82e01e6-0bd0-1a44-957d-1e1544593af6%40aegee.org.
For more options, visit https://groups.google.com/d/optout.

Reply via email to