我想对使用 MySQL 数据库的代码运行一些测试。现在,代码由多个模块组成,所有模块都导入一个公共(public)模块 mainlib
。该模块执行以下操作
db = MySQLdb.connect(host='localhost', user='admin', password='admin', db='MyDatabase').
我想使用测试数据库而不是真实数据库进行测试。
我想我可以关闭连接(mainlib.db.close()
)并在测试脚本中创建一个新连接:
db = MySQLdb.connect(host='localhost', user='admin', password='admin', db='TestDatabase')
并使用相同的全局变量命名新游标。但我不确定其他模块中的导入是如何工作的。无论如何,此方法似乎不起作用,因为我收到 InterfaceError: (0, '')
并且没有从我的测试数据库 cursor
返回数据。
有谁知道如何在不修改源代码的情况下切换到测试数据库?
最佳答案
Python 的“全局”变量没有全局作用域。它们是模块范围的变量。所以不同模块中的同名全局变量并不是同一个变量。
我认为您可能会关闭 mainlib.db
,然后将 mytestcode.db
设置为新数据库。当然,所有其余代码继续使用 mainlib.db
,但现已关闭。
尝试mainlib.db = MySQLdb.connect(...)
,对于游标也是如此。直接修改另一个模块的变量很丑陋,但它可以按您的预期工作。
另一种方法是引入一种配置 mainlib
如何打开数据库的方法。例如,您可以在 mainlib
中拥有这样的函数:
db = None
dbname = None
cursor = None
def connectdb(name = None):
"""
Set up the global database connection and cursor, if it isn't already.
Omit 'name' when the caller doesn't care what database is used,
and is happy to accept whatever database is already connected or
connect to a default database.
Since there cannot be multiple global databases, an exception is thrown
if 'name' is specified, the global connection already exists, and the
names don't match.
"""
global db, dbname, cursor
if db is None:
if name is None:
name = 'MyDatabase'
db = MySQLdb.connect(host='localhost', user='admin', password='admin', db=name)
dbname = name
cursor = db.cursor()
elif name not in (None, dbname):
raise Exception('cannot connect to the specified db: the global connection already exists and connects to a different db')
现在,在您的正常程序中(不是在每个模块中,只是在顶层),您在导入 mainlib
后立即调用 mainlib.connectdb()
。在测试代码中,您调用 mainlib.connectdb('TestDatabase')
。
或者,您可以让connectdb
返回游标和/或连接对象,这样,使用全局数据库的所有内容都可以通过此函数。
就我个人而言,我根本不喜欢使用全局变量——我将有一个函数来创建数据库连接,并且我会将该数据库作为参数传递给任何需要它的东西。然而,我意识到在这方面品味有所不同。
关于python - MySQLdb Python - 测试数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18969525/