我有一系列集成级测试,这些测试作为Django项目中的管理命令运行。这些测试正在验证从外部来源摄入到我的数据库中的大量天气数据的完整性。因为我有大量的数据,所以我真的必须对照我的生产数据库进行测试,这样测试才会有意义。我想弄清楚的是,如何定义一个特定于该命令或连接对象的只读数据库连接。我还应该补充一点,这些测试不能通过ORM,所以我需要执行原始SQL。
我的测试结构看起来像这个
class Command(BaseCommand):
help = 'Runs Integration Tests and Query Tests against Prod Database'
def handle(self,*args, **options):
suite = unittest.TestLoader().loadTestsFromTestCase(TestWeatherModel)
ret = unittest.TextTestRunner().run(suite)
if(len(ret.failures) != 0):
sys.exit(1)
else:
sys.exit(0)
class TestWeatherModel(unittest.TestCase):
def testCollectWeatherDataHist(self):
wm = WeatherManager()
wm.CollectWeatherData()
self.assertTrue(wm.weatherData is not None)
WeatherManager.CollectWeatherData((方法如下所示:
def CollecWeatherData(self):
cur = connection.cursor()
cur.execute(<Raw SQL Query>)
wm.WeatherData = cur.fetchall()
cur.close()
我想以某种方式证明这一点,这样其他人(或我(就不会稍后出现,意外地编写一个修改生产数据库的测试。
您可以通过挂接Django的connection_created
信号来实现这一点,并且然后使事务为只读。
以下适用于PostgreSQL:
from django.db.backends.signals import connection_created
class MyappConfig(AppConfig):
def ready(self):
def connection_created_handler(connection, **kwargs):
with connection.cursor() as cursor:
cursor.execute('SET default_transaction_read_only = true;')
connection_created.connect(connection_created_handler, weak=False)
这对于某些特定的Django设置(例如运行开发针对生产数据库使用runserver
的代码(创建一个真正的只读数据库用户。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mydb',
'USER': 'myusername',
'PASSWORD': 'mypassword',
'HOST': 'myhost',
'OPTIONS': {
'options': '-c default_transaction_read_only=on'
}
}
}
来源:https://nejc.saje.info/django-postgresql-readonly.html
伙计,在这里发布问题之前,我应该再次仔细阅读文档。我可以在设置文件中定义到生产数据库的只读连接,然后直接从文档中定义:
如果使用多个数据库,则可以使用django.db.connections获取特定数据库的连接(和游标(。django.db.connections是一个类似字典的对象,它允许您使用别名检索特定的连接
from django.db import connections
cursor = connections['my_db_alias'].cursor()
# Your code here...
如果为您的模型添加一个序列化程序,您可以专门化在只读模式中工作的序列化程序
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('id', 'account_name', 'users', 'created')
read_only_fields = ('account_name',)
来自http://www.django-rest-framework.org/api-guide/serializers/#specifying-只读字段