Django测试:临时数据库文件中没有数据

时间:2012-02-16 11:19:15

标签: python django sqlite django-testing django-database

我正在settings.py中使用sqlite3数据库设置如下:

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.spatialite',
        'NAME': 'path/to/config.sqlite',
        'TEST_NAME': 'path/to/test-config.sqlite',
        # ... USER, PASSWORD and PORT left out for brevity
    }
}

在测试运行期间开始:

python manage.py test myapp.mytest

这暂时创建了一个数据库文件path/to/test-config.sqlite,我需要在另一个加载了所需夹具的应用程序中。

然而,数据库文件是空的,我在一次测试暂停期间断言:

sqlite> select * from someapp_somemodel;

... no results here :(

其他不需要sqlite文件并且内存数据库足够的测试用例,不会发生错误。

我的问题:

  • 为什么django无法将数据刷新到数据库文件中?和
  • 我如何说服django这样做,因为我要求将数据转储到临时数据库文件中?

编辑

我正在使用Django 1.3.1,如果有兴趣的话。

EDIT2

我熟悉灯具,我用它们来填充数据库,但我的问题是在测试过程中夹具的数据没有写入数据库文件。对不起,如果我对这个事实不够清楚。

EDIT3

由于我的问题需要澄清,请考虑以下测试设置(这与我实际做的很接近):

class SomeTestCase(django.test.TestCase):
    fixtures = ["some_fixture.json", "some_other_fixture.json"]

    def testSomething(self):
        import pdb; pdb.set_trace()

testSomething方法遇到断点时,我启动sqlite3程序并连接到Django创建的临时数据库文件。加载了固定装置(我知道,因为其他测试也起作用),但数据不会写入临时数据库文件。

5 个答案:

答案 0 :(得分:1)

您是否运行了初始syncdb来创建数据库表? ( python yourproject / manage.py syncdb

在您的settings.py中,您在INSTALLED_APPS下安装了哪些应用?

在您的项目中,您构建了哪些模型?

根据您在INSTALLED_APPS中安装的应用以及已添加到项目中的自定义模型,将决定syncdb将创建的数据库。

答案 1 :(得分:1)

也许这与how Django tests use transactions有关?

如果您在settings.py:

turn off all transactions,请检查问题是否仍然存在
DISABLE_TRANSACTION_MANAGEMENT = True

答案 2 :(得分:1)

来自django documentation

  

...使用SQLite数据库引擎时,默认情况下将使用测试   内存数据库(即数据库将在内存中创建,   彻底绕过文件系统!)。如果你想使用不同的   数据库名称,在字典中为任何给定指定TEST_NAME   DATABASES中的数据库。

此外,如果您read about fixture loading

  

...在每个测试用例开始时,在运行setUp()之前,Django将刷新数据库,在调用syncdb后将数据库返回到它所处的状态...

如果您需要一个装有一些灯具的新数据库,您当然可以通过创建一个运行syncdb的空数据库并使用django-admin.py loaddata加载一些灯具来实现此目的!

答案 3 :(得分:1)

根据您的数据库引擎'django.contrib.gis.db.backends.spatialite',您似乎正在使用 GeoDjango 。 GeoDjango需要额外的设置,所以我的猜测是它还需要一些额外的测试。 (如果你没有使用GeoDjango,只需使用'django.db.backends.sqlite3'作为数据库引擎。保留TEST_NAME,否则Django会在内存中创建测试数据库。)

加载空间数据有一个完整的过程,GeoDjango安装文档非常全面。这是一个直接创建SpatiaLite database的链接。你需要为测试做同样的事情。

来自testing docs

  

您需要下载SpatiaLite的初始化SQL脚本:

     

$ wget http://www.gaia-gis.it/spatialite/init_spatialite-2.3.zip

     

$ unzip init_spatialite-2.3.zip

     

如果 init_spatialite-2.3.sql 与项目的manage.py位于同一路径中,那么您所要做的就是:   $ python manage.py test

答案 4 :(得分:1)

我找到了一种方法,但是由于我也使用了hdparm(使用-F或-W 0/1),我不知道它是否适合你。我重新启动并重新尝试确保思考。此外,这个测试有SpatiaLite,但正如你所说,这可能是无关紧要的。

无论如何,我们需要2个屏幕才能重现这一点, screen0运行测试并且 screen1是一个sh shell 可以使用屏幕0的进程暂停。

开始测试(screen0):

>>> ./manage.py test testapp
Creating test database for alias 'default'...
Destroying old test database 'default'...
Type 'yes' if you would like to try deleting the test database 'db_test.sqlite', or 'no' to cancel: yes
--Return--
None
> /home/jpic/testproject/testapp/tests.py(16)testSomething()
     14 
     15     def testSomething(self):
---> 16         import ipdb; ipdb.set_trace()

检查创建的测试数据库文件的大小,(screen1):

<<< 18:00.39 Mon Feb 20 2012!~/testproject 
<<< jpic@germaine!10004 env
>>> ls -l db_test.sqlite
-rw-r--r-- 1 jpic jpic 49152 2012-02-20 18:00 db_test.sqlite

从python运行PRAGMA SYNCHRONOUS sql命令(screen0):

ipdb> from django.db import connection; cursor = connection.cursor()
ipdb> cursor.execute("PRAGMA SYNCHRONOUS")
<django.db.backends.sqlite3.base.SQLiteCursorWrapper object at 0x294f348>
ipdb> 

检查数据库文件的大小是否增加(screen1):

<<< 18:00.42 Mon Feb 20 2012!~/testproject 
<<< jpic@germaine!10005 env
>>> ls -l db_test.sqlite
-rw-r--r-- 1 jpic jpic 272384 2012-02-20 18:00 db_test.sqlite

数据已写入文件。

这对我来说没有多大意义,因为显然只有PRAGMA SYNCHRONOUS should just query for the value (在我的情况下:2 / FULL)。但在实践中,它写入磁盘。请注意,如果您没有2(FULL),则应将其设置为2:PRAGMA SYNCHRONOUS 2

现在,我不能说写了什么(它是完全写的?)因为我无法抓住测试数据库:如果我在screen1中运行sqlite db_test.sqlite在测试数据库上获取客户端:我无法运行任何命令(也不能选择,也不能运行.dump),因为“SQL错误:数据库被锁定”。但是,我想现在这是你的问题B)