(第17回)Python mini Hack-a-thon
URL:http://connpass.com/event/279/#pyhack
□メモ
◯JavaからPythonの気持ち悪い部分
・privateがない
・thisがself
・多重継承
◯Pythonでネットからダウンロードできる
python -m urllib
◯僕が今日やること「Python3.2.2+SQLAlchemy連携」をsqlite以外で使いたい
→sqliteは動くが本番には使えないだろうし、mongoDBとかやると挫折しそうだしそもそもSQLAlchemyで動かないので
・「PyMySQL3」を試す
URL:http://pypi.python.org/pypi/PyMySQL3/
→すでにインストールしてたが、実行時に bytearrayのPython3特有のエラー
(fb_env)shinriyo:teaspoon shinriyo$ python . create => 11:36:45 : creating the database. 2012-03-24 11:36:47,481 INFO sqlalchemy.engine.base.Engine SELECT DATABASE() 2012-03-24 11:36:47,482 INFO sqlalchemy.engine.base.Engine {} Traceback (most recent call last): File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/pool.py", line 717, in _do_get return self._pool.get(wait, self._timeout) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/util/queue.py", line 137, in get raise Empty sqlalchemy.util.queue.Empty During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/opt/python-3.2.2/lib/python3.2/runpy.py", line 160, in _run_module_as_main "__main__", fname, loader, pkg_name) File "/opt/python-3.2.2/lib/python3.2/runpy.py", line 73, in _run_code exec(code, run_globals) File "/Users/shinriyo/ve/fb_env/tmp/teaspoon/__main__.py", line 78, in <module> eval(argv[1])() File "/Users/shinriyo/ve/fb_env/tmp/teaspoon/__main__.py", line 46, in create __create__() File "./models/__init__.py", line 29, in <lambda> __create__ = lambda: (setattr(engine, 'echo', True), metadata.create_all(engine)) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/schema.py", line 2556, in create_all tables=tables) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 2291, in _run_visitor conn = self.contextual_connect(close_with_result=False) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 2478, in contextual_connect self.pool.connect(), File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/pool.py", line 224, in connect return _ConnectionFairy(self).checkout() File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/pool.py", line 387, in __init__ rec = self._connection_record = pool._do_get() File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/pool.py", line 739, in _do_get con = self._create_connection() File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/pool.py", line 188, in _create_connection return _ConnectionRecord(self) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/pool.py", line 273, in __init__ pool.dispatch.first_connect.exec_once(self.connection, self) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/event.py", line 279, in exec_once self(*args, **kw) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/event.py", line 288, in __call__ fn(*args, **kw) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/strategies.py", line 168, in first_connect dialect.initialize(c) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/dialects/mysql/base.py", line 1977, in initialize default.DefaultDialect.initialize(self, connection) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/default.py", line 181, in initialize self._get_default_schema_name(connection) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/dialects/mysql/base.py", line 1942, in _get_default_schema_name return connection.execute('SELECT DATABASE()').scalar() File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 1450, in execute params) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 1627, in _execute_text statement, parameters File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 1716, in _execute_context result = context.get_result_proxy() File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/default.py", line 646, in get_result_proxy return base.ResultProxy(self) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 2892, in __init__ self._init_metadata() File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 2899, in _init_metadata self._metadata = ResultMetaData(self, metadata) File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/sqlalchemy/engine/base.py", line 2750, in __init__ if primary_keymap.setdefault(name.lower(), rec) is not rec: TypeError: unhashable type: 'bytearray'
・mopemopeさんのpure-python-mysqml
URL:https://github.com/mopemope/pure-python-mysql
動作環境:Python 2.4 かそれ以上(2.5が動作確認)
MySQL 4.1 かそれ以上
protocol41 をサポート
git clone https://github.com/mopemope/pure-python-mysql.git cd pure-python-mysql python setup.py install
→インストール時に例外のエラー
Traceback (most recent call last): File "setup.py", line 8, in <module> version_tuple = __import__('pymysql').VERSION File "/Users/shinriyo/ve/fb_env/tmp/pure-python-mysql/pymysql/__init__.py", line 3, in <module> from pymysql.exceptions import Warning, Error, InterfaceError, DataError, \ File "/Users/shinriyo/ve/fb_env/tmp/pure-python-mysql/pymysql/exceptions.py", line 122 raise errorclass, errorvalue ^ SyntaxError: invalid syntax
モジュール内を片っ端から「2to3」で変換(-wオプションを付けないと差分だけみられる)
2to3 -w *
・pymysql/exceptions.py
e = sys.modules['exceptions']
↑「exceptions」というキーはないと怒られる。
$ print(sys.builtin_module_names) ('__main__', '_ast', '_codecs', '_collections', '_functools', '_io', '_locale', '_sre', '_string', '_symtable', '_thread', '_warnings', '_weakref', 'builtins', 'errno', 'gc', 'imp', 'itertools', 'marshal', 'operator', 'posix', 'pwd', 'signal', 'sys', 'xxsubtype', 'zipimport')
↑確かに無い・・・、↓のように書き換えた
・pymysql/exceptions.py
#python2.x #try: # from .exceptions import Exception, Exception, Warning #except ImportError: # import sys # e = sys.modules['exceptions'] # Exception = e.Exception # Warning = e.Warning #Python3.x try: from .exceptions import Exception, Exception, Warning except ImportError: import sys pass
・何のためかわからないが、Exceptionをdelするコード↓があってエラーを吐くので、
del Exception, _map_error, ER
↑のコードが来る前のソースに、↓を書いておく(単に代入しただけだけど、正しいのか?)
Exception = Exception
・pymysql/__init__.py
→Python2.xはImmutableSetだったのが、Python3ではfrozensetのようだからImmutableSetとしてインポートする
#from sets import ImmutableSet #2.x from builtins import frozenset as ImmutableSet #3.x
・インストール成功??
$ sudo python setup.py install Password: running install running build running build_py running install_lib copying build/lib/pymysql/__init__.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql copying build/lib/pymysql/charset.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql copying build/lib/pymysql/connections.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql copying build/lib/pymysql/constants/__init__.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants copying build/lib/pymysql/constants/CLIENT_FLAG.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants copying build/lib/pymysql/constants/COMMAND.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants copying build/lib/pymysql/constants/ER.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants copying build/lib/pymysql/constants/FIELD_TYPE.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants copying build/lib/pymysql/constants/SERVER_STATUS.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants copying build/lib/pymysql/converters.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql copying build/lib/pymysql/cursor.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql copying build/lib/pymysql/exceptions.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql copying build/lib/pymysql/times.py -> /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/__init__.py to __init__.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/charset.py to charset.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/connections.py to connections.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants/__init__.py to __init__.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants/CLIENT_FLAG.py to CLIENT_FLAG.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants/COMMAND.py to COMMAND.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants/ER.py to ER.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants/FIELD_TYPE.py to FIELD_TYPE.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/constants/SERVER_STATUS.py to SERVER_STATUS.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/converters.py to converters.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/cursor.py to cursor.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/exceptions.py to exceptions.pyc byte-compiling /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/times.py to times.pyc running install_egg_info Writing /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/PyMySQL-0.1-py3.2.egg-info
↑「Writing /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/PyMySQL-0.1-py3.2.egg-info」
ってWarningっておもったら"Writing"だった。
・"SQLAlchemy"のcreate_engineメソッドに記載するドライバ指定は"pymysql"なのだろうか?
※他にも"pymysql"という名前のドライバがあるので競合するのでは?
(「example / simple.py」の一番上にはpymysqlとあった)
・example / simple.py
import pymysql
・念のため、以前インストールしたpipから「pymysql」をアンインストールしておく
pip uninstall pymysql
↓付属で入ってたサンプル「example/simple.py」を実行したがこうなった。
$ python simple.py Traceback (most recent call last): File "simple.py", line 5, in <module> password='ma2',db='sample') File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/__init__.py", line 53, in Connect from .connections import Connection File "/Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/connections.py", line 4, in <module> import sha ImportError: No module named sha
「site-packages」にある「connections.py」を2to3でコンバート(管理者権限必須)
sudo 2to3 /Users/shinriyo/ve/fb_env/lib/python3.2/site-packages/pymysql/connections.py
しかし、直らなかった
・「sha」がPython3からなくなってて、「hashlib」にあるみたいなので、
「connections.py」
#import sha #python2 from hashlib import sha1 as sha #python3
まだエラー
TypeError: expected an object with the buffer interface
・さらに"\0"の前にbytes型のリテラル表記の"b"が必要「connections.py」
#server_end = data.find("\0", i) #python2 server_end = data.find(b"\0", i) #python3
またエラー
TypeError: startswith first arg must be bytes or a tuple of bytes, not str
「connections.py」
#if self.server_version.startswith('5'): if self.server_version.startswith(b'5'):
TypeError: can't concat bytes to str
(bytes型と文字列型は連結できない)
詳しいサイトURL:http://d.hatena.ne.jp/bellbind/20081002/1222948118
・書き換えた(bつけたり、bytes()で)
#python2.x # data = (struct.pack('l', self.client_flag)) + "\0\0\0\x01" + \ # '\x08' + '\0'*23 + \ # self.user+"\0\x14" + _scramble(self.password, self.salt) #python3.x data = (struct.pack('l', self.client_flag)) + b"\0\0\0\x01" + \ b'\x08' + b'\0'*23 + \ bytes(self.user, "utf-8")+b"\0\x14" + _scramble(self.password, self.salt)
AttributeError: 'builtin_function_or_method' object has no attribute 'new'
sha(sha1をasで指定してインポートしたやつ)には、newのメソッドも関数もない。
・それぞれ変更した
#stage1 = sha.new(password).digest() stage1 = sha(password.encode("utf-8")).digest() #stage2 = sha.new(stage1).digest() stage2 = sha(stage1).digest()
まずmd5追加して、
from hashlib import md5
#s = sha.new()
s = md5()
result += struct.pack('B', x)
ここで、
TypeError: Can't convert 'bytes' object to str implicitly
なかなか直せない・・・・あきた
→続きお願いします!
https://github.com/shinriyo/pure-python-mysql3
・FirebirdもsqlalchemyやPython3が使えそう
URL:http://docs.sqlalchemy.org/en/latest/dialects/firebird.html
・FIrebird本体をおとす
http://sourceforge.net/projects/firebird/
・Python用ドライバ、kinterbasdb
URL:http://www.firebirdsql.org/en/python-driver/
→Firebird のドライバーがあるが作者が死亡してメンテナンスが長くおこなわれていないらしい。しかもPython2.x
・pypiにもあがってる
URL:http://pypi.python.org/pypi/firebirdsql/0.6.5
curl -O http://pypi.python.org/packages/source/f/firebirdsql/firebirdsql-0.6.5.tar.gz cd firebirdsql-0.6.5 python setup.py install
・SQLAlchemyのcreate_engineの引数でfirebird用ドライバの書き方がわからない
とりあえずfirebirdだけ書いてやってみる
engine = create_engine('firebird://teaspoon:teaspoon@localhost/teaspoon')
→「ImportError: No module named kinterbasdb」ってエラーが出るのでデフォルトは「kinterbasdb」を使うようだ
githubには「pyfirebirdsql」という名前だったので、「+pyfirebirdsql」を追加してみる。
engine = create_engine('firebird+pyfirebirdsql://teaspoon:teaspoon@localhost/teaspoon')
・しかし「pyfirebirdsql」なんて指定が出来なかった・・・。
sqlalchemy.exc.ArgumentError: Could not determine dialect for 'firebird+pyfirebirdsql'.
・PostgrSQL
・PostgrSQL用ドライバ「psycopg2」をPython3にポートしている人がいる
Blog:http://initd.org/psycopg/articles/2011/01/24/psycopg2-porting-python-3-report/
github:https://github.com/dvarrazzo/psycopg
・インストールした(難なくいけた)
git clone https://github.com/dvarrazzo/psycopg cd psycopg/ python setup.py install
・PostgrSQL本体ダウンロード(MacOSX)
ダウンロード元URL: http://www.postgresql.org/download/macosx/
ダウンロードしてインストール開始すると・・・
→READMEを見てメモリの設定か
・「/etc/sysctl.conf」に以下を記載した
kern.sysv.shmmax=1610612736 kern.sysv.shmall=393216 kern.sysv.shmmin=1 kern.sysv.shmmni=32 kern.sysv.shmseg=8 kern.maxprocperuid=512 kern.maxproc=2048
↓実行した
sysctl -a
PCを再起動したらいけた!
デフォのここにインストール。
/Library/PostgreSQL/9.1
・ポートや文字コード(?)これらもデフォ
Port:5432
Locale:[Default locale]→「ja_JP」にしたほうが良かったかも?日本語でのソートに影響が出るっぽいので。
・「/Applications/PostgreSQL/9.1」の「SQL Shell (psql)」を起動する