7

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

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。

编辑2

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

编辑3

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

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

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

testSomething方法运行到断点时,我启动sqlite3程序并连接到 Django 创建的临时数据库文件。夹具已加载(我知道,因为其他测试也可以正常工作),但数据未写入临时数据库文件。

4

5 回答 5

2

也许这与Django 测试如何使用事务有关

如果您关闭settings.py 中的所有事务,请检查问题是否仍然存在:

DISABLE_TRANSACTION_MANAGEMENT = True
于 2012-02-19T15:49:01.353 回答
1

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

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

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

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

于 2012-02-19T13:49:51.607 回答
1

django 文档

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

此外,如果您阅读有关夹具加载的信息

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

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

于 2012-02-19T21:53:56.367 回答
1

看起来您正在根据您的数据库引擎使用GeoDjango'django.contrib.gis.db.backends.spatialite'做一些事情, . GeoDjango 需要额外的设置,所以我猜它也需要一些额外的测试。(如果您不使用 GeoDjango,只需将'django.db.backends.sqlite3'其用作您的数据库引擎。TEST_NAME尽管如此,否则 Django 将在内存中创建测试数据库。)

加载空间数据有一个完整的过程,GeoDjango 安装文档非常详尽。这是直接创建SpatiaLite 数据库的链接。您需要为测试做基本相同的事情。

测试文档

您需要下载 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

于 2012-02-20T00:25:33.603 回答
1

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

无论如何,我们需要 2 个屏幕来重现这一点,screen0 运行测试,而screen1 是一个 sh shell,用于将 screen0 的进程暂停。

开始测试(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 (screen0)运行 PRAGMA SYNCHRONOUS sql 命令:

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单独应该只查询值(在我的情况下:2/FULL)。但在实践中,它会写入磁盘。请注意,如果您没有 2 (FULL) 那么您应该将其设置为 2: PRAGMA SYNCHRONOUS 2

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

于 2012-02-20T17:05:26.940 回答