Creating Objects from Annotations and Other Models

23 views
Skip to first unread message

Dylan Young

unread,
Mar 19, 2019, 11:34:11 AM3/19/19
to Django users
Hey all:

I often find myself fetching data from models in the database only to run a few trivial calculations and store the info in a different model.

Is there an established ORM pattern for directly creating objects in the DB based on the fields of other models?

Sorry if this is obvious, but I couldn't find much on this in my web searching. 


Best,

Casey 

Derek

unread,
Mar 21, 2019, 1:51:57 AM3/21/19
to Django users
Permanently storing data that can be recalculated from existing data is a practice specific to the needs of particular applications.  

Have you perhaps considered making use of the "view" table functionality available in most databases?

For example, in PostgreSQL you can create a materialized view which "caches the result of a complex expensive query and then allow you to refresh this result periodically." - see http://www.postgresqltutorial.com/postgresql-materialized-views/

Dylan Young

unread,
Mar 21, 2019, 12:19:35 PM3/21/19
to django...@googlegroups.com
It's not a recalculation. It's instantiation.

Instance data diverges from the factory data and needs to be independently editable. 

Best, 

Casey

--
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 django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/a1c55adc-c5fa-465c-8740-3a741bc22686%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dylan Young

unread,
Mar 21, 2019, 1:06:04 PM3/21/19
to django...@googlegroups.com
For example using made-up syntax:

Entry.objects.create(start=F(Recurrence.objects.filter(pk=r_id), 'start_time'))

Note that we can't use `get` since the whole point is to avoid all the useless round-trips to the DB.

Best,

Casey

Derek

unread,
Mar 21, 2019, 2:23:00 PM3/21/19
to django-users
Your use case is not very clear.

If you are simply "running a few trivial calculations and storing the info" then you could use a function in the database to do this for you - pulling data directly from Table A and storing the result in Table B. Data in Table B could then be later edited using the usual Django functionality.

As a  side note: a trip to the database to get data is not "useless" if you need that data for some reason and it is not already present in your app.

You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/RDU_KsRqd90/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users...@googlegroups.com.

To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.

Chasan KIOUTSOUK MOUSTAFA

unread,
Mar 21, 2019, 2:30:49 PM3/21/19
to django...@googlegroups.com
You can override the save method or simply use Django signals to modify fields of Model automatically.


For more options, visit https://groups.google.com/d/optout.


--
Kind Regards.
--------------------------------------------------
Chasan KIOUTSOUK MOUSTAFA, 
Freelance Software Engineer                      
www.chasank.com
--------------------------------------------------

Simon Charette

unread,
Mar 21, 2019, 4:06:27 PM3/21/19
to Django users
I'm not sure where r_id comes from but Model.save usually deals with any expression correctly
so you could try using a subquery assignment and see if it works.

e.g.

entry = Entry.objects.create(
    start=Subquery(
        Recurrence.objects.filter(pk=r_id).values('start_time')[:1]
    )
)

Note that accessing entry.start right after creation might still return the Subquery instance
instead of the created value. This is caused by some backends not supporting the
RETURNING clause. There's an open ticket about making such attributes available
immediately on backend supporting RETURNING but it was still missing consensus about
what to do on other backends. If I remember correctly the two alternatives were to defer the
field or perform an immediate SELECT.

Cheers,
Simon

Dylan Young

unread,
Mar 21, 2019, 5:12:49 PM3/21/19
to django...@googlegroups.com
It's perfectly clear and precisely what an ORM is for.

If you don't have an answer, just say so, though I suspect the answer is use SubQuery.

It is not "useless" in general (obviously if you want to display/ deliver to an end user,  you need to pluck from the database).  It is useless in the case I am asking about. 



Dylan Young

unread,
Mar 21, 2019, 5:15:25 PM3/21/19
to django...@googlegroups.com
Thanks Simon. That's exactly what I'm looking for. Wish they had piggy backed in the established F pattern though.  It's quite verbose just to access the field on either model. 

r_id would just be a pk, usually from a fk on another model that I do need to fetch.


Best, 

Casey 




Reply all
Reply to author
Forward
0 new messages