Skip to main content
 首页 » 编程设计

python之缓慢保存到 Django 数据库

2025年05月04日32wuhuacong

我创建了一个自定义 manage.py命令如下:

from django.contrib.auth.models import User 
from django.core.management.base import BaseCommand 
from photos.models import Person 
 
 
class Command(BaseCommand): 
    help = 'Pre-populate database with initial data' 
 
    def _create_people(self, user): 
        for i in range(0, 100): 
            person = Person(first_name='FN', surname='SN', added_by=user) 
            person.save() 
 
    def handle(self, *args, **options): 
        user = User.objects.get(username="user1") 
        self._create_people(user) 

我已经为 handle() 计时了执行,如果我不这样做,大约需要 0.02 秒 person.save()每 Person 约 0.1 秒如果我保存。数据库是 sqlite,我相信它应该更快。什么可以解释如此糟糕的性能?我该如何改进?

请您参考如下方法:

分析:

def _create_people(self, user): 
   for i in range(0, 100): 
     person = Person(first_name='FN', surname='SN', added_by=user) 
     # Hits the database for each save. 
     person.save() 

此函数将访问数据库 100 次并每次自动提交,这就是导致性能低下的原因(不考虑 sqlite 与 MySQL 或 PostgreSQL 相比的低性能)。

改进:

你这里需要的是 bulk_create它将使用类构造函数 创建的对象数组作为输入。所以一个可能的解决方案如下:

def _create_people(self, user): 
   person_data = {"first_name": "FN", "surname":"SN", "added_by": user} 
   person_list = [Person(**person_data) for i in range(100)] 
   Person.objects.bulk_create(person_list) 

By default bulk_create hits the DB once no matter how many objects, except in SQLite (In SQLite it's about 999 per query.). How many objects can be created in a single query can be specified through the parameter batch_size.

注意:

  • save() will not be called, and the related signals will not be sent.
  • does not work with m2m relationships.