【问题标题】:Saving many Django objects with one big INSERT statement用一个大的 INSERT 语句保存许多 Django 对象
【发布时间】:2011-07-16 17:52:23
【问题描述】:

假设你有以下情况:

for i in xrange(100000):
  account = Account()
  account.foo = i
  account.save

显然,Django 执行的 100,000 个INSERT 语句需要一些时间。能够将所有这些INSERTs 合并成一个大INSERT 会更好。这是我希望我能做的事情:

inserts = []

for i in xrange(100000):
  account = Account()
  account.foo = i
  inserts.append(account.insert_sql)

sql = 'INSERT INTO whatever... ' + ', '.join(inserts)

有没有办法使用 QuerySet 来做到这一点,而无需手动生成所有这些 INSERT 语句?

【问题讨论】:

标签: python django


【解决方案1】:

in this related question 所示,可以使用@transaction.commit_manually 将所有.save() 操作组合为一次提交,从而大大提高性能。

@transaction.commit_manually
def your_view(request):
    try:
        for i in xrange(100000):
            account = Account()
            account.foo = i
            account.save()   
    except: 
        transaction.rollback()
    else:
        transaction.commit() 

或者,如果您喜欢冒险,请查看this snippet,它实现了批量插入管理器。请注意,它仅适用于 MySQL,并且有一段时间没有更新,因此很难判断它是否可以与较新版本的 Django 一起使用。

【讨论】:

  • 这对大多数引擎几乎没有影响,除了 SQLite 可能。您仍在实例化数千个模型并运行数千个单独的 SQL 插入。
  • (更准确地说,这取决于数据库后端和配置;它可能会有所帮助,但根据我使用批处理 INSERT INTO ... FROM VALUES 的经验,这更重要。)
  • 我正在使用 MySQL InnoDB 和 MyISAM,这种方法确实有所作为(快 100 倍以上)
  • commit_manually 已被放弃;目前(1.11),可能会使用atomic
【解决方案2】:

您可以使用原始 SQL。

通过Account.objects.raw() 或使用 django.db.connection 对象。

如果您想保持数据库不可知论,这可能不是一个选项。

http://docs.djangoproject.com/en/dev/topics/db/sql/

如果您正在做的是一次性设置,也许使用固定装置会更好。

【讨论】:

  • 这是我试图避免的,但看看其他答案/cmets,看起来这可能是我必须做的。
  • 这就是我最终要做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-03
  • 2021-01-10
  • 1970-01-01
  • 2012-07-06
  • 1970-01-01
  • 2010-12-28
  • 1970-01-01
相关资源
最近更新 更多