我正在尝试在两个django安装(生产和测试)之间同步数据.我正在使用./manage.py dumpdata --natural生产,然后./manage.py loaddata进入一个新syncdb的测试数据库.
在我添加新的自定义权限之前,一切正常.生产syncdb以不同的顺序(使用不同的主键)加载此新权限,而不是syncdb空数据库上的新权限.因此,它获得了不同的ID.因此,尽管使用自然键,当我尝试加载数据时,我在加载第一个无序权限对象时收到此错误:
IntegrityError: duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key"
Run Code Online (Sandbox Code Playgroud)
我能想到解决这个问题的最简单方法是从测试安装中的每个表中删除所有数据 - 也就是说,syncdb仅用于创建表,而不是用于加载初始数据.但是syncdb不要让你跳过初始数据/信号步骤.如果没有明确枚举每个模型或表名,如何在调用后删除所有初始数据syncdb?或者有没有办法只使用空表创建syncdb?
./manage.py flush 不是我所追求的 - 它重新加载初始数据并触发syncdb信号.
根据flush命令的帮助(我正在使用Django 1.3.1),执行的SQL与从中获取的SQL相同./manage.py sqlflush,然后重新安装初始数据夹具.
$ python manage.py help flush
Usage: manage.py flush [options]
Executes ``sqlflush`` on the current database.
Run Code Online (Sandbox Code Playgroud)
要获得相同的数据擦除功能减去夹具加载,您可以通过调用获取SQL ./manage.py sqlflush,然后使用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()
Run Code Online (Sandbox Code Playgroud)
这具有额外的好处,您可以./manage.py sqlflush在执行之前修改SQL,以避免擦除您可能希望保留原样的表.
另外,根据当前的Django文档,在Django 1.5中,新参数./manage.py flush --no-initial-data将重置数据而不加载初始数据夹具.