2013-09-23 2 views
0

Я хотел бы запустить несколько тестов для кода, который использует базу данных MySQL. Сейчас код состоит из нескольких модулей, которые импортируют общий модуль mainlib. Этот модуль делаетMySQLdb Python - тестовые базы данных

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.

Кто-нибудь знает, как переключиться на тестовую базу данных без изменения исходного кода?

+0

@Steve, спасибо; это сработало. Если вы ответите, я бы выбрал его. Также, если у вас есть идеи о том, как переконфигурировать 'mainlib' как более красивое решение, дайте мне знать! – newt

ответ

1

"глобальные" переменные Python не имеют глобальный масштаб. Они являются переменными модуля. Таким образом, одноименный глобальный в разных модулях не является одной и той же переменной.

Я думаю, что вы можете закрыть mainlib.db, а затем установить mytestcode.db в новую базу данных. Остальная часть вашего кода, конечно же, продолжает использовать mainlib.db, который теперь закрыт.

Попробуйте mainlib.db = MySQLdb.connect(...), и то же самое для курсора. Непосредственное изменение переменных другого модуля является уродливым, но оно работает так, как вы ожидали.

Альтернативой может быть введение способа настройки способа открытия 0BБД. Например, вы могли бы иметь такую ​​функцию в 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 курсор и/или объект соединения. Таким образом, все, что использует глобальный db, может пройти через эту функцию.

Лично я предпочитаю не использовать глобальные переменные для этого вообще - у меня была бы функция создания соединения с базой данных, и я передал бы эту базу данных в качестве параметра во все, что в ней нуждается. Однако я понимаю, что в этом отношении разные вкусы.

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 
+0

Я мог бы сделать это в своем тестовом скрипте, но остальные мои модули (которые я вызываю в своем тестовом скрипте) будут продолжать использовать реальную базу данных. – newt

Смежные вопросы