web-dev-qa-db-ja.com

MySQLデータベースをPython

AnacondaディストリビューションのPython 3.4を使用します。このディストリビューション内で、別のコンピューターにある既存のMySQLデータベースに接続するためのpymysqlライブラリーを見つけました。

import pymysql
config = {
      'user': 'my_user',
      'passwd': 'my_passwd',
      'Host': 'my_Host',
      'port': my_port
    }

    try:
        cnx = pymysql.connect(**config)
    except pymysql.err.OperationalError : 
        sys.exit("Invalid Input: Wrong username/database or password")

ここで、アプリケーションのテストコードを記述します。このコードでは、すべてのテストケースのsetUpに、できればメモリ内に非常に小さなデータベースを作成します。ただし、これをpymysqlで突然試してみると、接続できません。

def setUp(self):
    config = {
      'user': 'test_user',
      'passwd': 'test_passwd',
      'Host': 'localhost'
    }
    cnx = pymysql.connect(**config)

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 61] Connection refused)")

私はグーグルで調べていて、SQLiteMySQLdbについていくつか見つけました。次の質問があります。

  1. sqlite3またはMySQLdbは、メモリ内にデータベースをすばやく作成するのに適していますか?
  2. Anacondaパッケージ内にMySQLdbをインストールするにはどうすればよいですか?
  3. setUpで作成されたテストデータベースの例はありますか?これもいい考えですか?

コンピューターでローカルに実行されているMySQLサーバーがありません。

13

Pymysql、MySQLdb、およびsqliteはどちらも、実際のデータベースも接続する必要があります。コードをテストするだけの場合は、テストするモジュールでpymysqlモジュールをモックし、それに応じて使用する必要があります(テストコードでは、ハードコードされた結果を事前定義されたSQLステートメントに返すようにモックオブジェクトを設定できます)

ネイティブPythonモックライブラリのドキュメントを確認してください: https://docs.python.org/3/library/unittest.mock.html

または、Python 2: https://pypi.python.org/pypi/mock

6
jsbueno

testing.mysqldpip install testing.mysqld)を使用してmysqlデータベースをモックできます。

いくつかの 発生するノイズの多いエラーログ のため、テストするときはこの設定が好きです:

import testing.mysqld
from sqlalchemy import create_engine

# prevent generating brand new db every time.  Speeds up tests.
MYSQLD_FACTORY = testing.mysqld.MysqldFactory(cache_initialized_db=True, port=7531)


def tearDownModule():
    """Tear down databases after test script has run.
    https://docs.python.org/3/library/unittest.html#setupclass-and-teardownclass
    """
    MYSQLD_FACTORY.clear_cache()


class TestWhatever(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.mysql = MYSQLD_FACTORY()
        cls.db_conn = create_engine(cls.mysql.url()).connect()

    def setUp(self):
        self.mysql.start()
        self.db_conn.execute("""CREATE TABLE `foo` (blah)""")

    def tearDown(self):
        self.db_conn.execute("DROP TABLE foo")

    @classmethod
    def tearDownClass(cls):
        cls.mysql.stop()  # from source code we can see this kills the pid

    def test_something(self):
        # something useful
4
Roman