概要
PythonでPostgreSQLで接続するにはpsycopg2
がよく使われますが
AWSのLambdaにserverless frameworkを使用してデプロイして実行する際にpsycopg2でハマってしまったのでPure Python
のpg8000
を使用しました
インストール
pip install pg8000
接続
import pg8000
conn = pg8000.connect(
user='<user>',
host='<host>',
database='<db>',
password='<password>'
)
# こんな感じもok
conf = {
user='<user>',
host='<host>',
database='<db>',
password='<password>'
}
conn = pg8000.connect(**conf)
SELECT
とりあえずテーブルはこんな感じで
id | name | age | from | language |
---|---|---|---|---|
1 | shimizu | 23 | nagano | python |
2 | kondo | 22 | kanagawa | java |
3 | saito | 23 | kanagawa | javascript |
cur = conn.cursor()
sql = 'SELECT * FROM user'
cur.execute(sql)
results = cur.fetchall()
for row in results:
print(row)
'''
[1, 'shimizu', 23, 'nagano', 'python']
[2, 'kondo', 22, 'kanagawa', 'java']
[3, 'saito', 23, 'kanagawa', 'javascript']
'''
cur.close()
conn.close()
クエリの実行結果はlist
を格納したtuple
として渡されます
INSERT
cur = conn.cursor()
kojima = (4, 'kojima', 23, 'aichi', 'python')
users = (
(5, 'kobayashi', 24, 'kanagawa', 'java'),
(5, 'maeda', 24, 'tokyo', 'swift'),
)
sql = '''
INSERT INTO user(id, name, age, from, language)
VALUES(%s, %s, %s, %s, %s)
'''
try:
cur.execute(sql, kojima)
cur.executemany(sql, users)
conn.commit()
except Exception as e:
print(e)
cur.close()
conn.close()
プレースホルダ(%s
)を利用してtuple
をINSERTしています
ちなみに以下のようにするとオートコミットになります
conn.autocommit = True
プレースホルダの種類
execute()
する前に以下のように設定すると、プレースホルダのパラメータスタイルを変更できます。
pg8000.paramstyle = 'named'
format(デフォルト): %s
おそらく何も設定していない状態だと%s
が適用されます
execute()
の第2引数のtuple
から順番に適用されます
qmark: ?
%s
が?
に変わっただけです
sql = '''
INSERT INTO user(id, name, age, from, language)
VALUES(?, ?, ?, ?, ?)
'''
try:
pg8000.paramstyle = 'qmark'
cur.execute(sql, (4, 'kojima', 23, 'aichi', 'python'))
conn.commit()
except Exception as e:
print(e)
named: :hoge
phpのpdo
を使っている人は馴染み深いかなと思います
execute()
の第2引数としてdict
を渡すことができます
:<dictのkey名>
とdictのkeyが対応して、keyに紐づいたvalueが適応されます
sql = '''
INSERT INTO user(id, name, age, from, language)
VALUES(:id, :name, :age, :from, :language)
'''
user = {
'id': 4,
'name': 'kojima',
'age': 23,
'from': 'aichi',
'language': 'python'
}
try:
pg8000.paramstyle = 'named'
cur.execute(sql, user)
conn.commit()
except Exception as e:
print(e)
pyformat: %(hoge)s
:named
とそんなに変わらないです
sql = '''
INSERT INTO user(id, name, age, from, language)
VALUES(%(id)s, %(name)s, %(age)s, %(from)s, %(language)s)
'''
user = {
'id': 4,
'name': 'kojima',
'age': 23,
'from': 'aichi',
'language': 'python'
}
try:
pg8000.paramstyle = 'pyformat'
cur.execute(sql, user)
conn.commit()
except Exception as e:
print(e)
その他
paramstyle
は上記で挙げた以外にもあります 参考(github)
もちろんexecute()
だけでなくexecutemany()
にも対応しています
UPSERT
今回記事を書いたきっかけとしてUPSERT
をしたかったのでUPSERT
も載せときます
sql = '''
INSERT INTO user(id, name, age, from, language)
VALUES(:id, :name, :age, :from, :language)
ON CONFLICT ON CONSTRAINT user_pkey
DO UPDATE SET
id=:id, name=:name, age=:age, from=:from, language=:language
'''
serverless frameworkについて
今回はパッケージ管理はpipenv
を使用しています
pipenv install pg8000
pipenv
で作成したPipfile
を一緒にデプロイするツールとしてserverless-python-requirementsを使用しています
最後に
今回はpg8000
を使用しましたが、serverless-python-requirements
のdockerizePip: non-linux
を使用すればAWSのLambda用にDockerイメージからビルドしてくれるようなので、psycopg2
使用できるかもしれません