import MySQLdb で実際にクエリを実行できるか確認する

mysqlclient をインストールしたので、実際にクエリを実行できるか簡単に確認します。

今回は WordPress で自動作成されたテーブルで、現在公開されている記事のタイトルを select しました。

% python3
Python 3.9.0 (default, Jan  3 2021, 10:29:59) 
[GCC 4.2.1 20070831 patched [FreeBSD]] on freebsd9
Type "help", "copyright", "credits" or "license" for more information.

>>> import MySQLdb
>>> conn = MySQLdb.connect(host='mysqlXXX.db.sakura.ne.jp', db='abcabc_notemite',user='abcabc',passwd='xxxxxxxxxxxx',charset='utf8mb4')
>>> c = conn.cursor()
>>> c.execute('select post_title from nm_posts where post_status = "publish"')
20
>>> c.fetchall()
(('サンプルページ',), ('【Wordpress】ショートコードを別ファイル管理でリスク低減',), ('【WordPress】ショートコードの表示・非表示を一発で切り替えたい',), ('【ターミナル】Mac のログインシェルを zsh に変える',), ('【Python】Macbook に Python3 をインストール',), ('【Python】「pip install requests」でエラー「pip3 install requests」で成功',), ('【Python】Mac に Beautifulsoup4 をインストール',), ('Homebrew を Macbook Pro へインストール',), ('Homebrew を使って Macbook に Wget をインストール',), ('【Wordpress】確かに「--」と書いたのに「–」と表示される件',), ('【8ステップでがんばる】さくらレンタルサーバーでWordPressサイト立ち上げ',), ('【ターミナル】さくらのレンタルサーバーにSSHでログインする方法',), ('さくらレンタルサーバに Python3 をインストールする方法',), ('【Python】さくらレンタルサーバーに requests モジュールをインストール',), ('【Python】Mac に MySQL モジュールをインストールする方法',), ('【2020年10月〜12月】YouTube 急上昇入りランキング',), ('さくらレンタルサーバーに libffi をインストールする',), ('【2020年1月〜】YouTube 急上昇入りランキング',), ('さくらレンタルサーバーで Python3 を再インストール',), ('【Python3】mysqlclient のために _ctypes と格闘した記録',))
>>> 

execute() の実行結果(上記「20」の部分)はクエリの結果として返されたレコード数を表示しています。fetchall() を実行しないとクエリの実行結果は見れないんですね。

【Python3】mysqlclient のために _ctypes と格闘した記録

経緯

さくらのレンタルサーバー上で MySQL のデータベースを使えるので、それを Python で操作したいと思ったのが始まりです。mysqlclient を使えば良いらしかったので「pip3 install mysqlclient」を実行するも、エラーが出て成功しない。なんとかインストールを終えるまでの過程が文系の私には?だいぶややこしかったのでその記録を書き留めます。

  1. 問題発生1(No module named '_ctypes')
  2. 調査と原因1(libffi が無い)
  3. libffi をインストール(sudo は使えない)
  4. 問題発生2(INFO: Could not locate ffi libs and/or headers)
  5. 調査と原因2(./configure 文の修正)
  6. 解決(mysqlclient インストール成功)

問題発生1(No module named '_ctypes')

上記の通り「pip3 install mysqlclient」を実行したところ、下記のエラーが出てインストールが失敗しました。

ModuleNotFoundError: No module named '_ctypes'

直訳すると「_ctypes モジュールがありません」

_ctypes モジュールとはなんぞや。そしてそれはどこにあるのでしょうか。。。

調査と原因1(libffi が無い)

取り敢えず知識ゼロから出来ることは、情報の海に身を投げてなんとなくわかるまで溺れること。。。調べた結果断片的ですが自分の理解できる範囲で下記の情報が得られました。

  • Python の _ctypes は C 言語で書かれたライブラリを Python から利用するためのモジュールであり、libffiに依存している。
  • ソースからPythonをビルドする際、libffiが見つからない場合は _ctypes のビルドはスキップされる。
  • つまり、libffi がない状態で Python をインストールしたため、_ctypes のビルドがされていなかった。
  • _ctypes がビルドされていない Python から _ctypes を利用しようとすると、当該エラー(ModuleNotFoundError: No module named '_ctypes')が発生する。
  • 当該エラーを解消するには、libffi をインストールした上で Python を再ビルド・再インストールする必要がある。

libffi をインストール(sudo は使えない)

「sudo apt-get install -y libffi-dev」というコマンドが出てきましたが、さくらのレンタルサーバー(スタンダード)では管理者権限が与えられていないので sudo が使えません。

% sudo apt-get install -y libffi-dev
/usr/local/bin/sudo: Permission denied.

この通り、拒否されてしまいます。諸々調べた結果下記の方法でインストール出来ました。

問題発生2(INFO: Could not locate ffi libs and/or headers)

めでたく libffi をインストール出来たので Python をインストールし直しました。が、念のため make のログを確認したところ下記を発見。

INFO: Could not locate ffi libs and/or headers

Failed to build these modules:
_ctypes               _zoneinfo 

直訳すると「ffi libs およびヘッダーが見つからず _ctypes モジュールと _zoneinfo モジュールをビルド出来ませんでした。」とのこと。ショック。

しょうがないのでとりあえず続けて make install しましたが、当然 _ctypes モジュールが無いので「pip3 install mysqlclient」を実行しても前回と全く同じエラーで失敗します。

ModuleNotFoundError: No module named '_ctypes'

調査と原因2(./configure 文の修正)

また海に放り出されました。今回は「INFO: Could not locate ffi libs and/or headers」の文言を頼りに調べました。

こちらのページ(英語)を見たところ、どうやら CPPFLAGS、LDFLAGS、PKG_CONFIG_PATH の設定が必要みたいです。PKG_CONFIG_PATH の設定は libffi のインストールの時に行っていたので、取り敢えず CPPFLAGS と LGFLAGS だけでやってみます。

python-3.9.0.tgz は残して他を消し、再度下記の「./configure」文で Python のインストールを試してみます。

./configure --prefix=$HOME/local/python/ --with-system-ffi LDFLAGS="-L $HOME/local/lib/" CPPFLAGS="-I $HOME/local/include/"
項目雑なメモ
--prefixPython3 をインストールする場所
--with-system-ffilibffi のシステムバージョンへの接続を有効にするスイッチ。
CPPFLAGSCプリプロセッサのオプション
include パスを入れるっぽい?
LDFLAGSリンク用のディレクトリを指定する。
lib フォルダを入れるっぽい?

解決(mysqlclient インストール成功)

上記の「./configure」文のあとで make を実行しました。そしてログを確認すると下記の通り _ctypes のエラーはなくなりました。_zoneinfo は何かよくわかりませんし特に今回必要だとも思ってないので無視します。

Failed to build these modules:
_zoneinfo

今回は「pip3 install mysqlclient」も無事成功しました。

% pip3 install mysqlclient
Collecting mysqlclient
  Using cached mysqlclient-2.0.3.tar.gz (88 kB)
Using legacy 'setup.py install' for mysqlclient, since package 'wheel' is not installed.
Installing collected packages: mysqlclient
    Running setup.py install for mysqlclient ... done
Successfully installed mysqlclient-2.0.3
WARNING: You are using pip version 20.2.3; however, version 20.3.3 is available.
You should consider upgrading via the '/home/halekaa/local/python/bin/python3.9 -m pip install --upgrade pip' command.
%