0

我想为使用 MySQL 数据库的代码运行一些测试。现在,代码由多个模块组成,它们都导入一个公共模块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

有谁知道如何在不修改源代码的情况下切换到测试数据库?

4

2 回答 2

1

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.connectdb()在导入mainlib. 在您调用的测试代码mainlib.connectdb('TestDatabase')中。

或者,您可以connectdb返回游标和/或连接对象,这样,使用全局数据库的所有内容都可以通过此函数。

就个人而言,我根本不喜欢使用全局变量——我将拥有一个创建数据库连接的函数,并将该数据库作为参数传递给任何需要它的东西。但是,我意识到在这方面的口味各不相同。

于 2013-09-24T09:06:10.350 回答
0

一个快速的解决方法是使用相同的游标,但在选择表时对数据库是明确的。例如,如果您在两个数据库中都有一个表 T。

你可以做

select * from myDatabase.T   #if you want to use the real table

或者

select * from TestDatabase.T  #if you want to use the test table
于 2013-09-23T21:56:58.087 回答