Using a database with Flask
Using a database with Flask
前回に引き続き Head First Python, 2nd Edition - O'Reilly Media の内容。
今度はDBを使用する。
ローカル環境でDBを使う
Mac に DB 環境を構築する。
MariaDB をインストール
書籍の中では MySQL 推しだったが、MariaDB でも互換あるから大丈夫よということなので MariaDB を使ってみる。
インストーラのダウンロードはこちらから。
Downloads | MariaDB
.pkg
ファイルなのでダイアログの通り進んでいけばインストール完了。
Installing MariaDB Server PKG packages on macOS - MariaDB Knowledge Base にある通り、以下のコマンドでrootログインできる。
sudo /usr/local/mariadb/server/bin/mariadb
パスワードは Mac にログインする際のもの。
DB とテーブルの作成
MariaDB に root ログインした状態でまずはDBを作成する。
MariaDB [(none)]> create database vsearchlogDB;
次に、作成したDBにアクセスできるIDとパスワードを作成する。
ユーザー名(vsearch)とパスワード(vsearchpasswd)をそれぞれ指定する。
MariaDB [(none)]> grant all on vsearchlogDB.* to 'vsearch' identified by 'vsearchpasswd'; MariaDB [(none)]> quit
作成したIDでログインし直す。
$ /usr/local/mariadb/server/bin/mariadb -u vsearch -p vsearchlogDB Password:
テーブルを作成する。
MariaDB [vsearchlogDB]> create table log ( -> id int auto_increment primary key, -> ts timestamp default current_timestamp, -> phrase varchar(128) not null, -> letters varchar(32) not null, -> ip varchar(16) not null, -> browser_string varchar(256) not null, -> results varchar(64) not null); Query OK, 0 rows affected (0.21 sec)
テーブルの内容を確認する。
MariaDB [vsearchlogDB]> describe log; +----------------+--------------+------+-----+---------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+---------------------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | ts | timestamp | NO | | current_timestamp() | | | phrase | varchar(128) | NO | | NULL | | | letters | varchar(32) | NO | | NULL | | | ip | varchar(16) | NO | | NULL | | | browser_string | varchar(256) | NO | | NULL | | | results | varchar(64) | NO | | NULL | | +----------------+--------------+------+-----+---------------------+----------------+ 7 rows in set (0.02 sec)
できとるできとる。
Python から DB 操作
Install MySQL-Connector/Python
Python から MariaDB, MySQL を操作するために Database Driver をインストールする。
MySQL / Download Connector/Python
取得して解凍するとmysql-connector-python-[バージョン]
ディレクトリができるのでここに移動。
仮想環境を activate した状態で以下を実行する。
$ python setup.py install running install Not Installing MySQL C Extension running build running build_py creating build creating build/lib creating build/lib/mysql copying lib/mysql/__init__.py -> build/lib/mysql creating build/lib/mysql/connector ・ ・ ・
これでインストール完了。
仮想環境の依存パッケージを確認してみる。
$ pip freeze apipkg==1.4 click==6.7 execnet==1.5.0 Flask==0.12.2 itsdangerous==0.24 Jinja2==2.10 MarkupSafe==1.0 mysql-connector-python==2.1.7 pep8==1.7.1 py==1.5.2 pytest==3.2.5 pytest-cache==1.0 pytest-pep8==1.0.6 vsearch==1.0 Werkzeug==0.14.1
入ってる入ってる。
Python コードからのDB操作
実際に Python >>> prompt から DB 操作してみる。
$ python Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08) [GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> dbconfig = { 'host': '127.0.0.1', ... 'user': 'vsearch', ... 'password': 'vsearchpasswd', ... 'database': 'vsearchlogDB', } >>> import mysql.connector >>> conn = mysql.connector.connect(**dbconfig) >>> cursor = conn.cursor() >>> _SQL = """show tables""" >>> cursor.execute(_SQL) >>> res = cursor.fetchall() >>> res [('log',)]
意図通り動作していることがわかる。
データの書き込みも試してみる。
>>> _SQL = """insert into log ... (phrase, letters, ip, browser_string, results) ... values ... (%s, %s, %s, %s, %s)""" >>> cursor.execute(_SQL, ('hitch-hiker', 'xyz', '127.0.0.1', 'Safari', 'set()')) >>> conn.commit()
commit を忘れないように。
書き込んだデータを確認してみる。
>>> _SQL = """select * from log""" >>> cursor.execute(_SQL) >>> for row in cursor.fetchall(): ... print(row) ... (1, datetime.datetime(2018, 2, 10, 8, 28, 14), 'hitch-hiker', 'xyz', '127.0.0.1', 'Safari', 'set()')
意図通り。
使い終わったら close する。
>>> cursor.close() True >>> conn.close()
PythonAnywhere で DB を使う
ここまでのセットアップでローカル環境ではDBが使えるようになった。
PythonAnywhere 上で公開しているアプリでもDBを使えるようにする。
DB のセットアップ
ローカル環境では MariaDB を選択したが、PythonAnywhere でサポートされているDBは以下の通り。
- MySQL
- SQLite
- Postgrs(有料アカウントでのみサポート)
Kinds of databases | PythonAnywhere help
今回は MariaDB と互換性のある MySQL を使用する。
PythonAnywhere の Databases タブで MySQL を選択する。
まずパスワードの設定を求められる。DBへのアクセス用だ。
Create a database で Dbatabase name を入力すれば DB 作成まで完了。
- ユーザー名は PythonAnywhere のユーザー名に固定される
- DB ホストアドレスも PythonAnywhere 側で決められる
- DB 名もこちらで指定したものに
ユーザー名+$
のプレフィックスを付けられる
といったルールがある模様。
ローカル環境でのconfigと分ける必要があるのでこんな感じにしてみた。
Add surpport for using DB on PythonAnywhere. · kfurue/hfpython-flask@01001ea
Create Table
DB は作成できたのでテーブルを作成していく。
DB タブに作成済みDBが表示され、Start a console on:
が表示されるのでクリックすれば、mysql>
コンソールにログインできる。
必要なテーブルを作成する。
mysql> create table log ( -> id int auto_increment primary key, -> ts timestamp default current_timestamp, -> phrase varchar(128) not null, -> letters varchar(32) not null, -> ip varchar(16) not null, -> browser_string varchar(256) not null, -> results varchar(64) not null); Query OK, 0 rows affected (0.03 sec) mysql> describe log; +----------------+--------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +----------------+--------------+------+-----+-------------------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | ts | timestamp | YES | | CURRENT_TIMESTAMP | | | phrase | varchar(128) | NO | | NULL | | | letters | varchar(32) | NO | | NULL | | | ip | varchar(16) | NO | | NULL | | | browser_string | varchar(256) | NO | | NULL | | | results | varchar(64) | NO | | NULL | | +----------------+--------------+------+-----+-------------------+----------------+ 7 rows in set (0.00 sec)
Install Database Driver
PythonAnywhere 上のコンソールを使用する。
Connector/Pythonをダウンロードして解凍する。
$ wget https://dev.mysql.com/get/Downloads/Connector-Python/mysql-connector-python-2.1.7.zip $ unzip mysql-connector-python-2.1.7.zip Archive: mysql-connector-python-2.1.7.zip $ cd mysql-connector-python-2.1.7/
PythonAnywhere上の仮想環境にインストールする。
$ workon my-virtualenv
インストール前の依存パッケージ一覧は以下の通り。
(my-virtualenv) $ pip freeze -f /usr/share/pip-wheels click==6.7 Flask==0.12.2 itsdangerous==0.24 Jinja2==2.10 MarkupSafe==1.0 vsearch==1.0 Werkzeug==0.14.1
ここに MySQL Connector/Python をインストールする。
(my-virtualenv) $ python setup.py install (my-virtualenv) $ pip freeze -f /usr/share/pip-wheels click==6.7 Flask==0.12.2 itsdangerous==0.24 Jinja2==2.10 MarkupSafe==1.0 mysql-connector-python==2.1.7 vsearch==1.0 Werkzeug==0.14.1
完了。
これで PythonAnywhere 上で公開しているアプリでも MySQL が使用できる。
その他
A beginner's guide to building a simple database-backed Flask website on PythonAnywhere - PythonAnyw
こんな記事もあったが、紹介されているのはSQLAlchemy。どっこい実装では MySQL Connector/Python を使用しているのでローカル環境と同じ方法でインストールした。
pip install -r requirements.txt
すればお手軽に環境コピーできるのが利点だったはずなのになんかそれ以外の手順が増えてきてしまった。
この辺りのベストプラクティスもきっとあるんだろうな。