Django:从每个表中删除所有数据(但保留表格本身)

时间:2011-10-28 18:25:40

标签: django

我正在尝试在两个django安装(生产和测试)之间同步数据。我在生产时使用./manage.py dumpdata --natural执行此操作,然后在./manage.py loaddata上使用新syncdb'ed数据库进行测试。

在我添加新的自定义权限之前,一切正常。生产syncdb以与空数据库上的新syncdb不同的顺序(使用不同的主键)加载此新权限。因此,它获得了不同的ID。因此,尽管使用自然键,当我尝试加载数据时,我在加载第一个无序权限对象时出现此错误:

IntegrityError: duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key"

我能想到解决此问题的最简单方法是从测试安装中的每个表中删除所有数据 - 即仅使用syncdb创建表,而不是加载初始数据。但syncdb不允许您跳过初始数据/信号步骤。如果没有明确枚举每个模型或表名,如何在调用syncdb后删除所有初始数据?或者有没有办法只使用syncdb创建空表?

./manage.py flush不是我追求的 - 它重新加载初始数据并触发syncdb信号。

2 个答案:

答案 0 :(得分:9)

根据flush命令的帮助(我正在使用Django 1.3.1),执行的SQL与从./manage.py sqlflush获得的SQL相同,然后重新安装初始数据夹具。

$ python manage.py help flush 
Usage: manage.py flush [options]

Executes ``sqlflush`` on the current database.

要获得相同的数据擦除功能减去夹具加载,您可以通过调用./manage.py sqlflush获取SQL,然后使用Django的内置支持执行该SQL以执行任意SQL:

from django.core.management import call_command, setup_environ
from your_django_project import settings
setup_environ(settings)

from django.db import connection
from StringIO import StringIO

def main():
    # 'call' manage.py flush and capture its outputted sql
    command_output = StringIO()
    call_command("sqlflush", stdout=command_output)

    command_output.seek(0)
    flush_sql = command_output.read()

    # execute the sql
    # from: https://docs.djangoproject.com/en/dev/topics/db/sql/#executing-custom-sql-directly
    cursor = connection.cursor()
    cursor.execute(flush_sql)

    print "db has been reset"

if __name__ == '__main__':
    main()

这样做的另一个好处是,您可以在执行之前从./manage.py sqlflush修改SQL,以避免擦除您可能希望保留原样的表。

此外,根据the current Django docs,在Django 1.5中,新参数./manage.py flush --no-initial-data将重置数据而不加载初始数据夹具。

答案 1 :(得分:0)

对于Django< = 1.4,您可以使用reset管理命令。

./manage.py sqlreset myapp1 myapp2