LoginSignup
4
3

More than 5 years have passed since last update.

【解決】GAEでCloudSQLに接続しようとしたら、dev_appserver の時だけ ImportError が出る

Last updated at Posted at 2017-07-27

研究で Google App Engine(Python) を利用していてハマっている。
Flask を使った Web サービスを GAE + CloudSQL で開発しており、 Flask から SQLAlchemy を使って CloudSQL に接続しようとしたところでエラーを吐く。
どうも MySQLdb を import しようとして ImportError: No module name _mysql のエラーが出ているらしい。
しかも、このエラーは dev_appserver.py でローカルで挙動を確認しようとしたときのみ起きる。

エラーログは以下の通り。
/user へのアクセスで sqlalchemy.create_engine() が実行されるところでエラーが出る)

$ dev_appserver.py app.yaml                                                                             
INFO     2017-07-27 05:57:06,227 sdk_update_checker.py:231] Checking for updates to the SDK.
INFO     2017-07-27 05:57:06,541 api_server.py:297] Starting API server at: http://localhost:52746
INFO     2017-07-27 05:57:06,545 dispatcher.py:209] Starting module "test" running at: http://localhost:8080
INFO     2017-07-27 05:57:06,548 admin_server.py:116] Starting admin server at: http://localhost:8000
WARNING  2017-07-27 05:57:06,548 devappserver2.py:187] No default module found. Ignoring.
INFO     2017-07-27 05:57:17,859 server.py:125] Server initialized for threading.
ERROR    2017-07-27 05:57:17,875 wsgi.py:263] 
Traceback (most recent call last):
  File "/Users/test/Desktop/study/gae/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 240, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File "/Users/test/Desktop/study/gae/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 299, in _LoadHandler
    handler, path, err = LoadObject(self._handler)
  File "/Users/test/Desktop/study/gae/google-cloud-sdk/platform/google_appengine/google/appengine/runtime/wsgi.py", line 85, in LoadObject
    obj = __import__(path[0])
  File "/Users/test/Desktop/test/test/main.py", line 30, in <module>
    engine = create_engine(url, echo=True)
  File "/Users/test/Desktop/test/test/lib/sqlalchemy/engine/__init__.py", line 387, in create_engine
    return strategy.create(*args, **kwargs)
  File "/Users/test/Desktop/test/test/lib/sqlalchemy/engine/strategies.py", line 80, in create
    dbapi = dialect_cls.dbapi(**dbapi_args)
  File "/Users/test/Desktop/test/test/lib/sqlalchemy/dialects/mysql/mysqldb.py", line 110, in dbapi
    return __import__('MySQLdb')
  File "/Users/test/Desktop/test/test/lib/MySQLdb/__init__.py", line 19, in <module>
    import _mysql
  File "/Users/test/Desktop/study/gae/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py", line 1024, in load_module
    raise ImportError('No module named %s' % fullname)
ImportError: No module named _mysql
INFO     2017-07-27 05:57:17,882 module.py:809] test: "GET /user HTTP/1.1" 500 -

(※秘匿したいところはだいたい test に置き換えてます)

app.yamlappengine_config.py は以下の通り。

app.yaml
module: test
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: /favicon\.ico
  static_files: favicon.ico
  upload: favicon\.ico

- url: .*
  script: main.app

libraries:
- name: MySQLdb
  version: "1.2.5"
appengine_config.py
from google.appengine.ext import vendor

# Add any libraries install in the "lib" folder.
vendor.add('lib')

ライブラリたちは lib ディレクトリに install している。

requirements.txt
Flask==0.10.1
Flask_SocketIO
itsdangerous==0.24
Jinja2==2.7.3
MarkupSafe==0.23
python-engineio
python-socketio
six==1.9.0
Werkzeug==0.10.4
sqlalchemy==1.1.9
mysql-python==1.2.5
$ sudo pip install -t lib -r requirements.txt

試しに、ローカルの Python で MySQLdb を import したらエラーは出なかった。

Python 2.7.9 (default, May  9 2017, 14:55:04) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb
>>> 

さらに試しに、 dev バージョンとしてGAE環境に上げてみたら問題なくデプロイされ、
問題なく CloudSQL への接続が確認できた。

$ appcfg.py -A test-project -V dev update app.yaml
03:15 PM Host: appengine.google.com
03:15 PM Application: test-project (was: None); module: test; version: dev (was: None)
03:15 PM Starting update of app: test-project, module: test, version: dev
03:15 PM Getting current resource limits.
03:15 PM Scanning files on local disk.
03:15 PM Scanned 500 files.
03:15 PM Cloning 544 application files.
03:15 PM Compilation starting.
03:16 PM Compilation completed.
03:16 PM Starting deployment.
03:16 PM Checking if deployment succeeded.
03:16 PM Deployment successful.
03:16 PM Checking if updated app version is serving.
03:16 PM Completed update of app: test-project, module: test, version: dev
$

ローカル環境に dev_appserver.py でデプロイしたときのみ、 _mysql が迷子になっている。

引き続き解決にあたる。
(ローカルで css や js の挙動確認ができないとしんどいなあ)


(追記: 2017/07/27 18:50)

ローカル環境に dev_appserver.py でデプロイしたときのみ、 _mysql が迷子になっている。

これを中心にぐぐっていくと、以下の stackoverflow にぶつかった。

google app engine - how to add lib folder?

appengine_config.py will run in the GAE environment or when you run dev_appserver, which emulates the GAE environment. However if you're ever running outside of a GAE environment, make sure your PYTHONPATH includes the lib folder you want to import from.

つまり、 ローカルで dev_appserver.py 実行した状態では appengine_config.py が実行されないので、 lib ディレクトリを PYTHONPATH に加えておけよ、とのこと。

実際にその通りに PYTHONPATH を設定し、

$ export PYTHONPATH=/Users/test/Desktop/test/test/lib:$PYTHONPATH

実行すると動いてくれた。

(その後、公式ドキュメントを読み漁ったが、 dev_appserver.pyappengine_config.py の関係が明記されてるものは見つからなかった...orz)

ひとまず解決してよかった。文章にまとめると問題点が整理されてよい。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3