Amazon RedshiftにアクセスするためのPython実行環境を整える(on Windows Server 2012)

2015.01.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

Amazon Redshiftへアクセスする為の環境作りエントリはこれまでも幾つか投稿して来ましたが、今回はPythonからアクセスする際の環境について、そのポイントをまとめながらご紹介して行きたいと思います。今回の環境はWindows系(Windwos Server 2012)/Python2.x系と言う組み合わせです。

目次

環境整備

まずはプログラム実施の為の環境構築手順のご紹介。都合3つの環境・ライブラリを導入して行きます。

Python 2.7

Python公式サイトより、Windowsのインストーラを入手します。

install-python-windows-01

導入する環境は64bit環境なので、対応する64bit版インストーラをダウンロードします。(64bit版指定では無いものでインストールすると、後述手順でエラーとなりますので注意してください)

install-python-windows-1022

インストーラを右クリックして『インストール』開始。

install-python-windows-101

インストール手順は基本デフォルトのままです。

install-python-windows-102

install-python-windows-103

Python.exeをPathに追加する指定を設定。

install-python-windows-104

インストール完了です。

install-python-windows-105

AWS SDK for Python(Boto)

AWS SDK for Python(Boto)はAWSの各種インスタンスや要素に関する操作を行うためのライブラリ群です。今回直接使う訳ではありませんが、ここでついでにインストールしときましょう。

インストーラは以下サイトから入手してください。

install-python-windows-11

上記Pythonを導入したフォルダ(C:\Python27\配下)のLibディレクトリに、ダウンロードしたbotoライブラリの解凍フォルダを配置。

install-python-windows-12

フォルダ配下に入っているsetup.pyを実行してインストール作業を実施。

C:\Python27\Lib\boto-2.35.1>dir
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 225E-3BC4 です

 C:\Python27\Lib\boto-2.35.1 のディレクトリ

2015/01/11  10:29    <DIR>          .
2015/01/11  10:29    <DIR>          ..
2015/01/11  10:17               123 .gitignore
2015/01/11  10:18    <DIR>          bin
2015/01/11  10:29    <DIR>          boto
2015/01/11  10:18    <DIR>          boto.egg-info
2015/01/11  10:29    <DIR>          build
2015/01/11  10:29    <DIR>          dist
2015/01/11  10:18    <DIR>          docs
2015/01/11  10:17               343 MANIFEST.in
2015/01/11  10:17             7,677 PKG-INFO
2015/01/11  10:17             8,865 pylintrc
2015/01/11  10:17             5,423 README.rst
2015/01/11  10:17                88 setup.cfg
2015/01/11  10:17             4,680 setup.py
2015/01/11  10:18    <DIR>          tests
               7 個のファイル              27,199 バイト
               9 個のディレクトリ  31,645,036,544 バイトの空き領域

C:\Python27\Lib\boto-2.35.1>python setup.py install
:
:
Installing sdbadmin script to C:\Python27\Scripts
Installing taskadmin script to C:\Python27\Scripts

Installed c:\python27\lib\site-packages\boto-2.35.1-py2.7.egg
Processing dependencies for boto==2.35.1
Finished processing dependencies for boto==2.35.1

C:\Python27\Lib\boto-2.35.1>

ちなみにbotoライブラリのAmazon Redshiftに関するAPIドキュメントは以下内容となります。

関連APIドキュメントからメソッドを抜き出してみました(例外関連要素は除く)。AWS CLI同様、Amazon Redshiftのクラスタや関連オブジェクトに関する操作が出来るものとなっています。

  • boto.redshift.connect_to_region
  • boto.redshift.regions
  • boto.redshift.layer1.RedshiftConnection
  • boto.redshift.layer1.RedshiftConnection.APIVersion
  • boto.redshift.layer1.RedshiftConnection.DefaultRegionEndpoint
  • boto.redshift.layer1.RedshiftConnection.DefaultRegionName
  • boto.redshift.layer1.RedshiftConnection.ResponseError
  • boto.redshift.layer1.RedshiftConnection.authorize_cluster_security_group_ingress
  • boto.redshift.layer1.RedshiftConnection.authorize_snapshot_access
  • boto.redshift.layer1.RedshiftConnection.copy_cluster_snapshot
  • boto.redshift.layer1.RedshiftConnection.create_cluster
  • boto.redshift.layer1.RedshiftConnection.create_cluster_parameter_group
  • boto.redshift.layer1.RedshiftConnection.create_cluster_security_group
  • boto.redshift.layer1.RedshiftConnection.create_cluster_snapshot
  • boto.redshift.layer1.RedshiftConnection.create_cluster_subnet_group
  • boto.redshift.layer1.RedshiftConnection.create_event_subscription
  • boto.redshift.layer1.RedshiftConnection.create_hsm_client_certificate
  • boto.redshift.layer1.RedshiftConnection.create_hsm_configuration
  • boto.redshift.layer1.RedshiftConnection.delete_cluster
  • boto.redshift.layer1.RedshiftConnection.delete_cluster_parameter_group
  • boto.redshift.layer1.RedshiftConnection.delete_cluster_security_group
  • boto.redshift.layer1.RedshiftConnection.delete_cluster_snapshot
  • boto.redshift.layer1.RedshiftConnection.delete_cluster_subnet_group
  • boto.redshift.layer1.RedshiftConnection.delete_event_subscription
  • boto.redshift.layer1.RedshiftConnection.delete_hsm_client_certificate
  • boto.redshift.layer1.RedshiftConnection.delete_hsm_configuration
  • boto.redshift.layer1.RedshiftConnection.describe_cluster_parameter_groups
  • boto.redshift.layer1.RedshiftConnection.describe_cluster_parameters
  • boto.redshift.layer1.RedshiftConnection.describe_cluster_security_groups
  • boto.redshift.layer1.RedshiftConnection.describe_cluster_snapshots
  • boto.redshift.layer1.RedshiftConnection.describe_cluster_subnet_groups
  • boto.redshift.layer1.RedshiftConnection.describe_cluster_versions
  • boto.redshift.layer1.RedshiftConnection.describe_clusters
  • boto.redshift.layer1.RedshiftConnection.describe_default_cluster_parameters
  • boto.redshift.layer1.RedshiftConnection.describe_event_categories
  • boto.redshift.layer1.RedshiftConnection.describe_event_subscriptions
  • boto.redshift.layer1.RedshiftConnection.describe_events
  • boto.redshift.layer1.RedshiftConnection.describe_hsm_client_certificates
  • boto.redshift.layer1.RedshiftConnection.describe_hsm_configurations
  • boto.redshift.layer1.RedshiftConnection.describe_logging_status
  • boto.redshift.layer1.RedshiftConnection.describe_orderable_cluster_options
  • boto.redshift.layer1.RedshiftConnection.describe_reserved_node_offerings
  • boto.redshift.layer1.RedshiftConnection.describe_reserved_nodes
  • boto.redshift.layer1.RedshiftConnection.describe_resize
  • boto.redshift.layer1.RedshiftConnection.disable_logging
  • boto.redshift.layer1.RedshiftConnection.disable_snapshot_copy
  • boto.redshift.layer1.RedshiftConnection.enable_logging
  • boto.redshift.layer1.RedshiftConnection.enable_snapshot_copy
  • boto.redshift.layer1.RedshiftConnection.modify_cluster
  • boto.redshift.layer1.RedshiftConnection.modify_cluster_parameter_group
  • boto.redshift.layer1.RedshiftConnection.modify_cluster_subnet_group
  • boto.redshift.layer1.RedshiftConnection.modify_event_subscription
  • boto.redshift.layer1.RedshiftConnection.modify_snapshot_copy_retention_period
  • boto.redshift.layer1.RedshiftConnection.purchase_reserved_node_offering
  • boto.redshift.layer1.RedshiftConnection.reboot_cluster
  • boto.redshift.layer1.RedshiftConnection.reset_cluster_parameter_group
  • boto.redshift.layer1.RedshiftConnection.restore_from_cluster_snapshot
  • boto.redshift.layer1.RedshiftConnection.revoke_cluster_security_group_ingress
  • boto.redshift.layer1.RedshiftConnection.revoke_snapshot_access
  • boto.redshift.layer1.RedshiftConnection.rotate_encryption_key

PostgreSQL接続ライブラリ(Psycopg2)

3つ目はPythonから利用出来るデータベース接続ライブラリの導入です。

Amazon Redshiftに接続する際のライブラリはPostgreSQLのものを転用する事とします。

下記エントリを見てみると、PostgreSQLへ接続するライブラリは幾つか存在しており、その中でもPsycopgというものが一番メジャーである様です。

下記URLから環境に対応したインストーラを入手します。今回はpsycopg2-2.5.4.win-amd64-py2.7-pg9.3.5-release.exeを利用しました。

インストーラ起動後はそのまま先に進めて手順を完了させてください。

install-python-windows-301

install-python-windows-302

install-python-windows-304

Psycopg2によるAmazon Redshiftへの接続確認

では、実際にライブラリを使用してAmazon Redshiftにアクセスしてみましょう。

PowerShellを管理者権限で起動し、pythonと入力。Python インタプリタを使って実践してみます。

install-python-windows-303

実践内容は以下の通りとなります。

  • 7行目:ライブラリpsycopg2のインポート。
  • 8行目:DB(Amazon Redshiftクラスタ)への接続情報を設定し、Connectionを取得。
  • 9行目:Connectionを使ってカーソルを生成。
  • 10行目:SQL実行。テーブルの件数を取得しています。
  • 11行目:Fecthコマンドを使って件数(3631)を取得。
  • 14行目:改めてSQL実行。今度はデータ内容を取得するSQLです。
  • 15行目:先程同様、取得結果を1件だけ(fetchone)取得。
Windows PowerShell
Copyright (C) 2014 Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator> python
Python 2.7.9 (default, Dec 10 2014, 12:28:03) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=xxxxx host=xxxxxxxxxxx user=xxxxx password=xxxxxxxx port=xxxx")
>>> cur = conn.cursor()
>>> cur.execute("SELECT COUNT(*) FROM public.all_entries;")
>>> cur.fetchone()
(3631L,)
>>>
>>> cur.execute("SELECT * FROM public.all_entries ORDER BY post_date DESC;")
>>> cur.fetchone()
(127389, datetime.datetime(2014, 12, 26, 4, 16, 39), 'Snappy Ubuntu Core\xe3\x82\x92Amazon EC2 Container Service\xe3\x81\xa7\xe4\xb
\x81\x86', 'https://dev.classmethod.jp/cloud/aws/snappy-using-amazon-ecs/', 'sasaki-daisuke                ', 3, 2, 0, 1, 7)
>>>
>>> conn.commit()
>>> cur.close()
>>> conn.close()
>>>
  • 4行目:上記同様のSQLを実行。
  • 5行目&6行目:for文を使い生成されている内容を順次出力しています。
>>> import psycopg2
>>> conn = psycopg2.connect("dbname=xxxxx host=xxxxxxxxxxx user=xxxxx password=xxxxxxxx port=xxxx")
>>> cur = conn.cursor()
>>> cur.execute("SELECT * FROM public.all_entries ORDER BY post_date DESC LIMIT 10;")
>>> for record in cur:
...     print record
...
(127389, datetime.datetime(2014, 12, 26, 4, 16, 39), 'Snappy Ubuntu Core\xe3\x82\x92Amazon EC2 Container Service\xe3\x81\xa7\xe4\xbd\xbf\xe3
\x81\x86', 'https://dev.classmethod.jp/cloud/aws/snappy-using-amazon-ecs/', 'sasaki-daisuke                ', 3, 2, 0, 1, 7)
(127350, datetime.datetime(2014, 12, 26, 3, 57, 27), '[Ruby on Rails]Active Job \xe2\x80\x93 \xe8\xa4\x87\xe6\x95\xb0\xe3\x81\xae\xe3\x82\xa
d\xe3\x83\xa5\xe3\x83\xbc\xe3\x82\x92\xe5\x84\xaa\xe5\x85\x88\xe9\xa0\x86\xe4\xbd\x8d\xe3\x82\x92\xe3\x81\xa4\xe3\x81\x91\xe3\x81\xa6\xe5\xa
e\x9f\xe8\xa1\x8c\xe3\x81\x99\xe3\x82\x8b', 'https://dev.classmethod.jp/server-side/ruby-on-rails/ruby-on-rails_active-job_queue_prioritize_c
arry_out/', 'honda-tetsuyuki               ', 12, 4, 0, 8, 11)
(127374, datetime.datetime(2014, 12, 26, 3, 50), '\xe3\x81\x93\xe3\x82\x8c\xe3\x81\x8b\xe3\x82\x89\xe3\x81\xaf\xe3\x81\x98\xe3\x82\x81\xe3\x
82\x8bGulp #25\xef\xbc\x9aHologram\xe3\x81\xa8gulp-hologram\xe3\x81\xa7\xe3\x82\xb9\xe3\x82\xbf\xe3\x82\xa4\xe3\x83\xab\xe3\x82\xac\xe3\x82\
xa4\xe3\x83\x89\xe3\x82\x92\xe4\xbd\x9c\xe3\x82\x8b', 'https://dev.classmethod.jp/client-side/javascript/gulp-solo-adv-cal-25/', 'nonaka-ryui
chi                ', 2, 1, 0, 1, 5)
:
:
(127157, datetime.datetime(2014, 12, 25, 2, 40, 49), '24: Intel Edison\xe5\xae\x9f\xe8\xb7\xb5\xe7\xb7\xa8 (4) \xe3\x80\x9c \xe3\x82\xbb\xe3
\x83\xb3\xe3\x82\xb5\xe3\x83\xbc\xe3\x83\x87\xe3\x83\xbc\xe3\x82\xbf\xe3\x82\x92CloudWatch\xe3\x81\xab\xe9\x80\x81\xe3\x81\xa3\xe3\x81\xa6\x
e3\x81\xbf\xe3\x82\x8b', 'https://dev.classmethod.jp/hardware/24-intel-edison-and-cloudwatch/', 'miyamoto-daisuke              ', 9, 4, 2, 3,
 21)

追記:Python3.4環境での実行

当エントリの実行環境は2.7で試していましたが、Python3.4でも念の為という事でやってみました。特に問題は無さそうです。

python34-install-01

python34-install-02

PS C:\Python34\Lib\boto-2.35.1> python .\setup.py install

python34-install-03

python-redshift.py

#coding: UTF-8
import psycopg2
import psycopg2.extensions

conn = psycopg2.connect("dbname=xxxxxxx host=xxxxxxxxxxxx user=xxxxxxx password=xxxxxxx port=5439")
cur = conn.cursor()
cur.execute("SELECT * FROM public.all_entries ORDER BY post_date DESC LIMIT 10;")
for record in cur:
	print( str(record[0])  + " " + record[2] )

(※注:デバッグ用に内容を出力していて遭遇したのですが、文字列中に\u2013のような文字が含まれていると出力時にエラーとなる様です。以下内容では上から2行目の内容がこれに合致しており、DB上で一旦文字置換を行っています。当環境での表示をしなければ差し支えない事象かも知れませんが、気になった部分だったので追記しておきました。)

PS C:\Python34> python .\python-redshift.py
127389 Snappy Ubuntu CoreをAmazon EC2 Container Serviceで使う
127350 [Ruby on Rails]Active Job - 複数のキューを優先順位をつけて実行する
127374 これからはじめるGulp #25:Hologramとgulp-hologramでスタイルガイドを作る
126435 ECMAScript 6の新しい構文をつかってみる#2
127353 Swiftのプログラムを書いてみよう - くらめそちゃんのSwiftパーティー(1)
126942 『箱根駅伝』を可視化してみた|Tableau Software Tips&Viz Advent Calendar 2014 #25 #tableau
126682 25: 都元と学ぶIoTアドベントカレンダーだった2014【まとめ】
127259 これからはじめるGulp #24:gulp.spritesmithプラグインでSpriteイメージを作る
127222 Edisonのボタン押下をイベントで取得してみる
127157 24: Intel Edison実践編 (4) ~ センサーデータをCloudWatchに送ってみる
PS C:\Python34>

追記2:Tableau 抽出APIと併用する場合の環境について

この環境下でTableau Extract APIを利用する場合、Pythonの環境は2.x系にしておく必要があります。Tableau Extract APIのREADME.txtを見ると、対応した記載が成されています。

README.txt

Tableau Data Extract API

Create extract files for use with Tableau's fast Data Engine.

================
= Requirements =
================
(*) Python 2.x with x >= 6
(*) The correct flavor (platform + architecture) version of this package.

================
= Installation = 
================
(1) python setup.py build
(2*) python setup.py install

[*] Run as root on POSIX platforms

まとめ

以上、PythonからのAmazon Redshift接続に関する実行環境構築手順まとめでした。スクリプト言語で(コンパイル等の必要無く)手軽にライブラリを利用し、DBアクセス出来るのは嬉しいところですね。PythonからはOS系のコマンド(バッチファイル等)も実行出来るので、この辺は有効活用して行きたいところです。こちらからは以上です。