Reputation: 4508
I have a django model called Friend
that contains a many to many field called friends
through another model called FriendshipInfo
. For performance reasons i decided to hold a field that holds the number of friends each person has. So now in the migration scripts i need to update the existing friends in my db. This is how i did it:
def forward(...):
# ... adding the new count field ...
for person in Friend.objects.all():
person.friends_count = len(persion.friends.all())
person.uupdate()
I was wondering if there is any way to do this in a much more efficient way (bulk update somehow?)
Tech info:
Upvotes: 1
Views: 316
Reputation: 1525
the right way it's in the migration file do the data migration (.py) there you can put the sql query without a problem, the method is migrations.RUNSQL here it's a example:
class Migration(migrations.Migration):
dependencies = [
('procesos', '0020_auto_20150703_1656'),
]
operations = [
migrations.RunSQL("UPDATE procesos_busquedainmueble SET tipo_inmueble_id=(filtros::json->>'tipo_inmueble')::int;"),
Upvotes: 0
Reputation: 4186
I was tempted to use the extra
queryset method to grab the count of friends and bulk update your Friend
objects like:
def forward(...):
# adding the new count field
Friend.objects.extra(select = {
'friends_number': 'SELECT COUNT(*) FROM <your_many_to_many_table_name> WHERE <your_many_to_many_table_name>.<your_FriendshipInfo_related_name> = <your_Friend_table_name>.id'
}).update(friends_count=F('friends_number'))
But, by the look of things, it is not possible. However, you can use the custom SQL queries with an update from count query:raw
method
from django.db import connection
def forward(...):
# adding the new count field
cursor = connection.cursor()
cursor.execute('\
UPDATE <your_Friend_table_name>\
SET friends_count = \
(SELECT COUNT(*) FROM <your_many_to_many_table_name> WHERE <your_many_to_many_table_name>.<your_FriendshipInfo_related_name> = <your_Friend_table_name>.id)')
Upvotes: 1