在运行Django测试前加载SQL转储
我有一个比较复杂的Django项目,这让使用数据文件来加载数据变得很困难,甚至不可能。
我想做的是在所有表格都由测试运行器创建之后、实际测试开始之前,从生产数据库服务器加载一个数据库备份。
我在MyTestCase.setUp()中尝试了各种“魔法”,但都没有成功。
如果有任何建议,我会非常感激。谢谢。
3 个回答
使用数据文件是最好的选择。你有没有试过用 ./manage.py dumpdata 从你当前的数据库创建一个数据文件?我还没见过这个在复杂模型上失败过,不过我想也有可能。
假设你在用mysql,你可以通过使用 mysqldump 来写一个脚本实现这个功能。
Django支持在进行数据库同步、重置或者启动测试时加载SQL文件,这正是你所描述的功能。
http://docs.djangoproject.com/en/dev/howto/initial-data/#providing-initial-sql-data
你需要在你的应用目录下创建一个名为“sql”的文件夹,然后在这个文件夹里放一个叫“mymodel.sql”的文件(其中“MyModel”是对应的模型名称)。
myproject/
|--myapp/
|--sql/
|--mymodel.sql
你可以使用数据库的转储工具来创建这个SQL文件。
- 对于SQLite:[1] 使用命令:echo '.dump' | sqlite3 yourdbname.sqlite > myapp/sql/mymodel.sql
- 对于MySQL:[2] 使用命令:mysqldump yourdbname > myapp/sql/mymodel.sql
- 对于PostgreSQL:[3] 使用命令:pg_dump yourdbname > myapp/sql/mymodel.sql
转储完成后,你需要编辑这个文件,只保留适当的INSERT语句,去掉其他复杂的内容。特别是,你必须删除事务处理、索引创建和表创建的SQL,以避免在加载重复创建语句时出现错误。
我使用这种方法来加载非常非常大的数据集——处理JSON数据太慢,而直接导入SQL则快得多。
请注意,这种方法会在每次调用同步、重置等操作时加载SQL,除了为测试运行器加载数据外,所以你无法为不同的测试用例使用不同的数据。如果你不想在重置后将这些数据加载回生产服务器,你需要在重置之前删除这些文件。
[1] http://www.sqlite.org/sqlite.html
[2] http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html
[3] http://www.postgresql.org/docs/8.1/static/backup.html#BACKUP-DUMP
你可能需要考虑定义一个自定义的测试运行器。这里有一些信息可以参考:https://docs.djangoproject.com/en/dev/topics/testing/advanced/#other-testing-frameworks
简单来说,我觉得你可以直接复制django.test.simple.run_tests中的默认测试运行器,然后根据你的需求进行修改。
我之前没有做过这个,但根据我的理解,这就是自定义的方式。