我正在尝试为Activty
个对象的大型(一次300多个)列表创建一个Inquiry
对象。我有一个ModelForm
正在回发,我需要创建单独的实例,并通过Inquiry
将它们附加到GenericForeignKey
。我们来看一些代码:
models.py:
class InquiryEntry(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
entry = generic.GenericForeignKey('content_type', 'object_id')
class Inquiry(models.Model):
entries = models.ManyToManyField('InquiryEntry')
# And many more fields.
def add_entry(self, obj):
entry = self.entries.create(entry=obj)
self.save()
return entry
class Activity(models.Model):
ts = models.DateTimeField(auto_now_add=True)
due_date = models.DateField(auto_now=False)
## And many more fields.
views.py:
def bulk_create_activities(request):
activity_form = ActivityForm()
if request.method == "POST":
activity_form = ActivityForm(request.POST)
if activity_form.is_valid():
pks = [int(x) for x in request.POST.get('pks', '').split(',')]
for inquiry in Inquiry.objects.filter(pk__in=pks):
instance = ActivityForm(request.POST).save()
inquiry.add_entry(instance)
inquiry.save()
我正在寻找的是一种将这些插入到数据库中的方法,最好是一次性传递,以便更快地处理请求。我不想放弃到数据库级别,因为这个应用程序是跨多个数据库供应商部署的,但如果这是继续进行的唯一方法,那么就是这样(MySQL和Postgres的例子很棒)。
注意:我知道开发版本中有bulk_create
,但在发布稳定版之前,这是不可能的。
答案 0 :(得分:3)
您是否尝试将for
封装在事务构造中?成功提交事务可以大大提高速度,因为条目会批量写入磁盘,因此DBMS不必在每个项目后停止fsync()。
在最新版本的django中实现事务是快速的,请查看 https://docs.djangoproject.com/en/dev/topics/db/transactions/#controlling-transaction-management-in-views
答案 1 :(得分:1)
我担心您可能需要drop to DB-API并使用cursor.executemany()。有关详细信息,请参阅PEP 249。
答案 2 :(得分:0)
您可以通过查看sql django生成的一些示例数据来获得一些提示(包括针对不同的数据库系统)。在调试模式下运行服务器将记录所有查询。你也可以通过
检查它们>>> from django.db import connection
>>> connection.queries
答案 3 :(得分:0)
查看http://people.iola.dk/olau/python/bulkops.py
它提供执行单个查询的insert_many和update_many函数。正如作者所指出的那样,你必须在python中为许多关系中的pks做一些手动记账,但是一旦你完成它们,你就可以在Inquiry
和InquiryEntry
上执行几个insert_many的操作。
答案 4 :(得分:0)
这不会使您的批量操作更有效,但如果Inquiry
不需要根据提交的数据即时响应(我假设基于型号名称),这听起来就像像芹菜这样的任务队列的完美工作。
用户将获得超快的响应,您的芹菜工人可以在闲暇时使用它。当1.4稳定时,请查看in_bulk:)
我也对数据库无关的坚如磐石的方法感兴趣,但根据你的情况,这可能是一个可接受的解决方案。
这里会看到答案......