在 Django 中测试不同的数据库?

发布于 2024-10-11 10:38:05 字数 796 浏览 3 评论 0原文

DATABASES = {
#    'default': {
#        'ENGINE': 'postgresql_psycopg2',
#        ...
#    }

    # for unit tests
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'mydatabase'
    }
}

我有两个数据库:一个我想用于单元测试,另一个用于其他一切。可以在 Django 1.2.4 中配置这个吗?

(我问的原因是因为使用 postgresql 我收到以下错误:

foo@bar:~/path/$ python manage.py test
Creating test database 'default'...
Got an error creating the test database: permission denied to create database

Type 'yes' if you would like to try deleting the test database 'test_baz', or 'no' to cancel: yes
Destroying old test database...
Got an error recreating the test database: database "test_baz" does not exist

为什么我会收到此错误?我想我并不真正关心我是否可以始终使用 SQLite 进行单元测试,因为这工作得很好。)

DATABASES = {
#    'default': {
#        'ENGINE': 'postgresql_psycopg2',
#        ...
#    }

    # for unit tests
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'mydatabase'
    }
}

I have two databases: one I'd like to use for unit tests, and one for everything else. Is it possible to configure this in Django 1.2.4?

(The reason I ask is because with postgresql I'm getting the following error:

foo@bar:~/path/$ python manage.py test
Creating test database 'default'...
Got an error creating the test database: permission denied to create database

Type 'yes' if you would like to try deleting the test database 'test_baz', or 'no' to cancel: yes
Destroying old test database...
Got an error recreating the test database: database "test_baz" does not exist

Why could I be getting this error? I guess I don't really care if I can always use SQLite for unit tests, as that works fine.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

信仰 2024-10-18 10:38:05

在您的 settings.py (或 local_settings.py)中:

import sys
if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'mydatabase'
    }

In your settings.py (or local_settings.py):

import sys
if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'mydatabase'
    }
冷情妓 2024-10-18 10:38:05

我处理这个问题的方法是通过拥有多个设置文件,因为我使用它来维护一组通用设置,并对每个实例进行修改。它的设置比其他一些解决方案要复杂一些,但无论如何我都需要这样做,因为我管理的本地开发、远程开发、暂存和生产的设置略有不同。

https://code.djangoproject.com/wiki/SplitSettings 有许多用于管理设置的选项,我已经选择了一种类似于 https://code.djangoproject.com/wiki/SplitSettings#SimplePackageOrganizationforEnvironments 中描述的实践

因此,在我的 Django 项目目录中,我有一个如下所示的设置文件夹:

$ tree settings
settings
├── defaults.py
├── dev.py
├── dev.pyc
├── __init__.py
├── lettuce.py
├── travis.py
├── unittest.py

常用设置位于 settings/defaults.py 中,我将它们导入到我的实例设置文件中。所以 settings/unittest.py 看起来像这样:

from defaults import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'my_database',
    }
} 

然后,当我想运行测试时,我只需执行:

$ ./manage.py test --settings=settings.unittest

使用 sqlite 进行测试。如果我想使用不同的测试运行程序或数据库配置,我将使用不同的设置模块。

The way I handle this is through having multiple settings files, since I use that to maintain a set of common settings with modifications for each instance. It's a little more complicated to set up than some of the other solutions, but I needed to do it anyway because I was managing slightly different settings for local development, remote development, staging and production.

https://code.djangoproject.com/wiki/SplitSettings has a number of options for managing settings, and I've chosen a practice similar to the one described at https://code.djangoproject.com/wiki/SplitSettings#SimplePackageOrganizationforEnvironments

So, in my Django project directory, I have a settings folder that looks like this:

$ tree settings
settings
├── defaults.py
├── dev.py
├── dev.pyc
├── __init__.py
├── lettuce.py
├── travis.py
├── unittest.py

The common settings are in settings/defaults.py and I import these in my instance settings files. So settings/unittest.py looks like this:

from defaults import *

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'my_database',
    }
} 

Then, when I want to run tests, I just execute:

$ ./manage.py test --settings=settings.unittest

to use sqlite for testing. I'll use a different settings module if I want to use a different test runner or database configuration.

岛歌少女 2024-10-18 10:38:05

您可以在settings.py中指定测试数据库。看
https://docs.djangoproject.com/en/ 3.0/topics/testing/overview/#the-test-database

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'mydatabaseuser',
        'NAME': 'mydatabase',
        'TEST': {
            'NAME': 'mytestdatabase',
        },
    },
}

You can specify test database in settings.py. See
https://docs.djangoproject.com/en/3.0/topics/testing/overview/#the-test-database

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'mydatabaseuser',
        'NAME': 'mydatabase',
        'TEST': {
            'NAME': 'mytestdatabase',
        },
    },
}
柳若烟 2024-10-18 10:38:05

我只需创建其他设置常量 DATABASES_AVAILABLE 就解决了这个问题。

DATABASES_AVAILABLE = {
    'main': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'nep',
        'USER': 'user',
        'PASSWORD': 'passwd',
        'HOST': 'localhost',
    },
    'remote': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'nes_dev',
        'USER': 'usr',
        'PASSWORD': 'passwd',
        'HOST': '200.144.254.136',
    },
    'sqlite': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
}

# This solves the problem with tests
# Define a system variable called DJANGO_DATABASE_TEST and set it to the
# the database you want
database = os.environ.get('DJANGO_DATABASE_TEST', 'main')
DATABASES = {
    'default': DATABASES_AVAILABLE[database]
}

I solved this issue simply creating other settings constant DATABASES_AVAILABLE.

DATABASES_AVAILABLE = {
    'main': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'nep',
        'USER': 'user',
        'PASSWORD': 'passwd',
        'HOST': 'localhost',
    },
    'remote': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'nes_dev',
        'USER': 'usr',
        'PASSWORD': 'passwd',
        'HOST': '200.144.254.136',
    },
    'sqlite': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
}

# This solves the problem with tests
# Define a system variable called DJANGO_DATABASE_TEST and set it to the
# the database you want
database = os.environ.get('DJANGO_DATABASE_TEST', 'main')
DATABASES = {
    'default': DATABASES_AVAILABLE[database]
}
我还不会笑 2024-10-18 10:38:05

这极大地加速了测试执行。

import sys

if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'TEST_CHARSET': 'UTF8', # if your normal db is utf8
        'NAME': ':memory:', # in memory
        'TEST_NAME': ':memory:', # in memory
    }

    DEBUG = False # might accelerate a bit
    TEMPLATE_DEBUG = False

    from django.core.management import call_command
    call_command('syncdb', migrate=True) # tables don't get created automatically for me

This accelerated dramatically test execution.

import sys

if 'test' in sys.argv:
    DATABASES['default'] = {
        'ENGINE': 'django.db.backends.sqlite3',
        'TEST_CHARSET': 'UTF8', # if your normal db is utf8
        'NAME': ':memory:', # in memory
        'TEST_NAME': ':memory:', # in memory
    }

    DEBUG = False # might accelerate a bit
    TEMPLATE_DEBUG = False

    from django.core.management import call_command
    call_command('syncdb', migrate=True) # tables don't get created automatically for me
少跟Wǒ拽 2024-10-18 10:38:05

您可以通过编辑 settings.py 来镜像您的数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'mydatabaseuser',
        'NAME': 'mydatabase',
        'TEST': {
            'MIRROR': 'default',
        },
    },
}

You can mirror your db by editing settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'mydatabaseuser',
        'NAME': 'mydatabase',
        'TEST': {
            'MIRROR': 'default',
        },
    },
}
深海里的那抹蓝 2024-10-18 10:38:05

虽然这已经解决了......

如果您的测试数据库只是一个普通的数据库:

我认为您没有进行单元测试,因为您依赖于数据库。无论如何,django 包含一个测试类型(不是统一的): django.test.TestCase

您需要从 django.test.TestCase 而不是unittest 派生。 TestCase 将为您创建一个新的 rehershal 数据库,该数据库将在测试结束时被销毁。

以下链接中有关于使用 db 进行测试的有趣解释/提示
测试 Django 应用程序

Though this is already solved...

If your database for tests is just a normal DB:

I think you are not doing unit test since you rely in the database. Anyway, django contains a test type for that (not unitary): django.test.TestCase

You need to derive from django.test.TestCase instead of unittest.TestCase that will create a fresh rehershal database for you that will be destroyed when the test end.

There are interesting explanations/tips about testing with db in the following link
Testing Django Applications

肥爪爪 2024-10-18 10:38:05

如果您有权手动创建数据库,则可以使用 django-nose 作为 TEST_RUNNER。安装后,如果传递以下环境变量,则不会删除并重新创建数据库。

REUSE_DB=1 ./manage.py test

您还可以将以下内容添加到settings.py,这样您就不必每次要运行测试时都编写REUSE_DB=1:

os.environ['REUSE_DB'] = "1"

注意:这也会将所有表保留在数据库中,这意味着测试设置会快一点,但是当您更改模型时,您将必须手动更新表(或自行删除并重新创建数据库)。

If you have access to manually create the database, you could use django-nose as your TEST_RUNNER. Once installed, if you pass the following environment variable, it will not delete and re-create the database.

REUSE_DB=1 ./manage.py test

You can also add the following to settings.py so you don't have to write REUSE_DB=1 every time you want to run tests:

os.environ['REUSE_DB'] = "1"

Note: this will also leave all your tables in the databases which means test setup will be a little quicker, but you will have to manually update the tables (or delete and re-create the database yourself) when you change your models.

儭儭莪哋寶赑 2024-10-18 10:38:05

我有你同样的问题。我解决了这个问题,只需在数据库中添加 settings.py 中的 TEST 值(在我的 Django 版本 4.0.2 中可用),方法如下:

DATABASES = {
     'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'HOST': host,
            'NAME': name,
            'TEST': {'NAME': 'test_db'},
            'USER': user,
            'PASSWORD': your_password,
    }
}.

此临时创建具有不同名称的数据库,并且解决了冲突。

I had your same issue. I resolved it just adding in settings.py the TEST value in the database, available in my Django version 4.0.2, in this way:

DATABASES = {
     'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'HOST': host,
            'NAME': name,
            'TEST': {'NAME': 'test_db'},
            'USER': user,
            'PASSWORD': your_password,
    }
}.

This temporary creates db with different name and the conflict is resolved.

薔薇婲 2024-10-18 10:38:05

为什么我会收到此错误?

因为权限不够。在使用超级用户权限运行 psql 后,您可以通过 ALTER USER username CREATEDB; 更改用户权限。

例子,

$ sudo su - postgres
$ psql
psql (9.3.18)
Type "help" for help.

postgres=# ALTER USER username CREATEDB;
ALTER ROLE

Why could I be getting this error?

Because of insufficient permissions. You can alter the user permissions by ALTER USER username CREATEDB; after running psql with superuser priviliges.

Example,

$ sudo su - postgres
$ psql
psql (9.3.18)
Type "help" for help.

postgres=# ALTER USER username CREATEDB;
ALTER ROLE
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文