如何在设置Django测试环境时创建外部数据库?

时间:2016-02-17 09:57:55

标签: python django postgresql testing

我的Django应用程序需要连接一个非托管(而不是Django)外部Postgres数据库。

为了测试我的项目,我需要使用原始SQL创建外部数据库和表,然后删除数据库。

通过阅读Django文档,可以使用现有的> head(mydata) Source: local data frame [2 x 2] criteria n (lgl) (int) 1 FALSE 4 2 TRUE 8 类创建自己的TestRunner类。可以重写DiscoverRunnersetup_test_environment方法来执行SQL以创建外部数据库:

teardown_test_environment

但是,当我运行测试时,收到以下错误消息:

from psycopg2 import connect from django.test.runner import DiscoverRunner class CustomTestRunner(DiscoverRunner): """ Test runner that helps to setup external db if doesn`t exist. """ def setup_test_environment(self, *args, **kwargs): conn = connect(database='postgres', host='localhost', user='my_user', password='password123') try: with conn.cursor() as c: query = """CREATE DATABASE "test_db" """ query += """WITH OWNER = my_user """ query += """ENCODING = 'UTF8' TABLESPACE = pg_default """ query += """LC_COLLATE = 'en_ZA.UTF-8' LC_CTYPE = 'en_ZA.UTF-8' """ query += """CONNECTION LIMIT = -1;""" c.execute(query) except Exception as e: print e conn.close() super(CustomTestRunner, self).setup_test_environment(*args, **kwargs) def teardown_test_environment(self, *args, **kwargs): super(CustomTestRunner, self).teardown_test_environment(*args, **kwargs) # Delete external database after tests try: conn = connect(database='postgres', host='localhost', user='my_user', password='password123') with conn.cursor() as c: query = """DROP DATABASE test_db;""" c.execute(query) except Exception as e: print e conn.close() conn.close()

是否可以在Django TestRunner中运行和提交SQL?如果没有,创建这样一个外部数据库的适当位置在哪里?

1 个答案:

答案 0 :(得分:1)

某些数据库命令(例如CREATE DATABASE)无法在事务中运行。您需要在数据库连接上设置适当的隔离级别:

conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)

请参阅http://initd.org/psycopg/docs/extensions.html#isolation-level-constants

也可以在测试运行器中运行和提交SQL。更合适的地方是setup_databsesteardown_databases方法。这是一个例子

def setup_databases(self, **kwargs):
    conn = connect(database='postgres', host='localhost', ...)
    try:        
        # set the proper isolation level so CREATE DATABASE works
        conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
        with conn.cursor() as cur:
            # execute SQL in here
            query = 'create database TEST_DB'
            cur.execute(query)
    finally:
        conn.close()

    return super(CustomTestRunner, self).setup_databases(**kwargs)

teardown_databases的实现应该非常相似。