My Django application needs to connect an unmanaged (not by Django) external Postgres database.
我的Django应用程序需要连接一个非托管(而不是Django)外部Postgres数据库。
For testing my project, I need to create the external DB and tables using raw SQL, and delete the DB afterwards.
为了测试我的项目,我需要使用原始SQL创建外部DB和表,然后删除DB。
From reading the Django documentation, one is able to create your own TestRunner class by using the existing DiscoverRunner
class. The setup_test_environment
and teardown_test_environment
methods could be overridden to execute the SQL in order to create the external DB:
通过阅读Django文档,可以使用现有的DiscoverRunner类创建自己的TestRunner类。可以重写setup_test_environment和teardown_test_environment方法来执行SQL,以创建外部DB:
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()
However, when I run the tests, I get the following error message:
然而,当我运行测试时,我得到以下错误消息:
CREATE DATABASE cannot run inside a transaction block
创建数据库不能在事务块中运行
Is it possible to run and commit SQL within a Django TestRunner? If not, where is the appropriate place to create such an external DB?
是否可以在Django TestRunner中运行和提交SQL ?如果不是,那么创建这样一个外部DB的合适位置在哪里?
1 个解决方案
#1
1
Some database commands such as CREATE DATABASE
can't run within a transaction. You'll need to set the proper isolation level on your database connection:
一些数据库命令,如CREATE database,不能在事务中运行。您需要在数据库连接上设置适当的隔离级别:
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
See http://initd.org/psycopg/docs/extensions.html#isolation-level-constants.
见http://initd.org/psycopg/docs/extensions.html # isolation-level-constants。
It is also possible to run and commit SQL within a test runner. The more appropriate places to do this would be in the setup_databses
and teardown_databases
methods. Here's an example
还可以在测试运行程序中运行和提交SQL。更合适的地方是setup_databses和teardown_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)
The implementation for teardown_databases
should be quite similar.
teardown_database的实现应该非常类似。
#1
1
Some database commands such as CREATE DATABASE
can't run within a transaction. You'll need to set the proper isolation level on your database connection:
一些数据库命令,如CREATE database,不能在事务中运行。您需要在数据库连接上设置适当的隔离级别:
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
See http://initd.org/psycopg/docs/extensions.html#isolation-level-constants.
见http://initd.org/psycopg/docs/extensions.html # isolation-level-constants。
It is also possible to run and commit SQL within a test runner. The more appropriate places to do this would be in the setup_databses
and teardown_databases
methods. Here's an example
还可以在测试运行程序中运行和提交SQL。更合适的地方是setup_databses和teardown_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)
The implementation for teardown_databases
should be quite similar.
teardown_database的实现应该非常类似。