Jupyter NotebookとMySQL X DevAPI
Pythonのコードを試すのに便利なJupyter Notebookを使って、Connector/PythonからMySQL X DevAPIを試す環境を作ってみました。Jupyter Notebookの利用には Anaconda に含まれるPythonとJupyter を使うことが強く推奨(strongly recommend)されています。
https://jupyter.org/install.html
ちなみにAnacondaは「データサイエンス向けに作成された Pythonパッケージ」と Python.jp で紹介されています。WindowsでもmacOSでもGUIのインストーラでさくさくインストールできます。
AnacondaへのConnector/Pythonのインストール
Anaconda.orgにパッケージをインストールする場合は conda install コマンドを使うとされています。
https://conda.io/docs/user-guide/tasks/manage-pkgs.html#installing-packages-from-anaconda-org
ところがAnaconda.orgには、標準のanacondaチャンネルではConnector/Python 2.0.4が、その他のチャンネルでも8.0系にバージョン番号ポリシーが変更される前の2.2.3が最新という状態で、Connector/Python 8.0をインストールすることができません。
https://anaconda.org/anaconda/mysql-connector-python
そこでnon-condaパッケージのインストールという手順を使います。
https://conda.io/docs/user-guide/tasks/manage-pkgs.html#installing-non-conda-packages
pipパッケージ管理ツールでmysql-connector-pythonパッケージをバージョン番号を指定して、Connector/Python 8.0.6をインストールします。
https://pypi.python.org/pypi/mysql-connector-python
# Anacondaの仮想環境の確認 sakila:~ sakila$ conda info --envs # conda environments: # root * /Users/sakila/anaconda3 # 仮想環境rootをアクティベート # Windowsではこのコマンドでエラーなくアクティベートできた # macOSではエラーになるのでエラーメッセージのsource付きコマンドを実行 sakila:~ sakila$ activate root Error: activate must be sourced. Run 'source activate envname' instead of 'activate envname'. sakila:~ sakila$ source activate envname CondaEnvironmentNotFoundError: Could not find environment: envname . You can list all discoverable environments with `conda info --envs`. sakila:~ sakila$ source activate root # pipコマンドでConnector/Python 8.0.6をインストール (root) sakila:~ sakila$ pip install mysql-connector-python==8.0.6 Collecting mysql-connector-python==8.0.6 Downloading mysql_connector_python-8.0.6-cp36-cp36m-macosx_10_12_x86_64.whl (3.2MB) 100% |======================================| 3.2MB 413kB/s Installing collected packages: mysql-connector-python Successfully installed mysql-connector-python-8.0.6
これでJupyter NotebookからConnector/Python 8.0.6を利用できるようになりました。
MySQL 8.0.4のインストールとX Pluginの登録
MySQL 8.0.4に関してはWindowsはZIP, LinuxやmacOSはTARを展開するのが手っ取り早いです。ちなみにWindows用のMySQL Installerは8.0.4が用意されていませんでした。--initializeまたは--initialize-insecureなどで初期化し、起動しておきます。
X DevAPIをサポートするためにX Pluginを登録します。
https://dev.mysql.com/doc/refman/8.0/en/document-store-setting-up.html
MySQL Shellがインストールしてあれば下記のコマンドでX Pluginが登録できます。
mysqlsh -u user -h localhost --classic --dba enableXProtocol
MySQL Shellがなければmysqlクライアントからサーバーに接続し、下記のコマンドを実行します。
mysql> INSTALL PLUGIN mysqlx SONAME 'mysqlx.so';
なおWindows上ではmysqlx.soだとファイルが見つからないためエラーとなるので、mysqlx.dllに変更します。
X DevAPIの動作確認のためJSONデータを含んだサンプルデータベースworld_xデータベースを下記からダウンロードし、展開してロードしておきます。
https://dev.mysql.com/doc/index-other.html
mysql -uroot < /foo/bar/world_x-db/world_x.sql
Jupyter Notebookからの動作確認
Anaconda Navigatorを起動しJupyter Notebookを選択します。起動直後のJupyter NotebookはWebブラウザ上にフォルダの一覧が表示される状態となっています。必要に応じてノート作成のフォルダを作成するか選択し、その後、画面右上のNewのプルダウンからPython 3を選択し、Notebookを新規作成します。
NotebookではIn [1]:の横のテキストボックスにPythonのコードを記載し、Shift + Enterで実行することができます。
まずは動作確認を兼ねて、Connector/Pythonのリファレンスマニュアルのサンプルコードを組み合わせて、稼働中のMySQLサーバーのバージョンをVERSION()関数で確認してみます。
from mysql.connector import (connection) cnx = connection.MySQLConnection(user='root', host='127.0.0.1') cur = cnx.cursor(buffered=True) cur.execute("SELECT VERSION()") print(cur.fetchone()) cur.close() cnx.close()
続いてSQLを変更して実際のデータとして先ほどインポートしたworld_xスキーマのcountryinfoテーブルのデータを取得してみます。このテーブルはCollectionとなるテーブル構造(JSON型の列とJSONドキュメント内の_id要素を抽出したGenerated Columnの_id列のみ、_id列は主キー)となっています。
mysql> desc world_x.countryinfo; +-------+-------------+------+-----+---------+------------------+ | Field | Type | Null | Key | Default | Extra | +-------+-------------+------+-----+---------+------------------+ | doc | json | YES | | NULL | | | _id | varchar(32) | NO | PRI | NULL | STORED GENERATED | +-------+-------------+------+-----+---------+------------------+ 2 rows in set (0.02 sec)
from mysql.connector import (connection) cnx = connection.MySQLConnection(user='root', host='127.0.0.1') cur = cnx.cursor(buffered=True) cur.execute("SELECT * FROM world_x.countryinfo") print(cur.fetchone()) cur.close() cnx.close()
Jupyter NotebookからのX Dev APIでのアクセス
先ほどと同様に、リファレンスマニュアルのサンプルコードを少し変更して、SQL文でもアクセスしたCollectionであるcountryinfoテーブルにX Dev APIでアクセスしてみます。ここでは10ドキュメント(=10行)取得して配列docに格納、その先頭レコードのうちName要素を取得して表示しています。インポート対象パッケージはmysqlxになっています。
import mysqlx # Connect to server on localhost session = mysqlx.get_session({ 'host': 'localhost', 'port': 33060, 'user': 'root', 'password': '' }) schema = session.get_schema('world_x') # Use the collection 'my_collection' collection = schema.get_collection('countryinfo') # Specify which document to find with Collection.find() result = collection.find().limit(10).execute() # Print document docs = result.fetch_all() print('Name: {0}'.format(docs[0]['Name'])) session.close()
ちなみにMySQLサーバーのユーザーにパスワードがない場合、ポート3306を使用するMySQL標準プロトコルの例では接続情報にパスワードに関する表記はなくても問題ありませんが、X Dev APIの場合は空文字を指定しないと接続時にエラーとなります。