SlideShare a Scribd company logo
1 of 21
Lisp tutorial for Pythonista.
Day #4 : Work with RDBMS




                                                          Ransui Iso
                           Strategic Technology Group, X-Listing Co, Ltd.
宿題できましたか?
今日は予告通り SQL !

なんだかんだで RDBMS 使えないと
   仕事では困っちゃう
CLSQL を使います
QuickLisp でインストール

clsql と clsql­mysql と clsql­postgresql
       をインストールしてくださいませ
REPL 環境下でテストしてみる

 ●   とりあえず select
CL­USER> (use­package :clsql)
CL­USER> (connect '("achernar" "stats_master" "<user­name>" "<password>")
             :database­type :mysql)
#<CLSQL­MYSQL:MYSQL­DATABASE achernar/stats_master/<user­name> OPEN {100343DEE1}>
CL­USER> (query "select id, client_id from campaign_base limit 2")
((1712 3736) (815 3371))
("id" "client_id")



 ●   多値関数なので…
CL­USER> (multiple­value­bind (rows field­names)
             (query "select * from campaign_base limit 2")
           (dolist (row rows)
             (loop :for value :in row
                   :for field­name :in field­names
                   :do (format t "~a : ~a~%" field­name value))
             (terpri)))
                                                (terpri) :標準出力に改行を送る関数
プログラムで使う場合は

●   例によって asdf でロードする
●
(asdf:oos 'asdf:load­op :clsql)
(asdf:oos 'asdf:load­op :clsql­mysql)
 ●
(asdf:oos 'asdf:load­op :clsql­postgresql)
      ●   SLIME の REPL で使う時も手動でロードしとく
      ●   Backend は使いたいやつだけで OK よ

●   パッケージ名は clsql
      ●   いちいちパッケージ名解決 (clsql:query ... ) とか面倒な人は
(use­package :clsql)

      ●   個人的には use-package はあまりオススメしないけどね。
      ●   Python で言うところの from clsql import * だし…
CLSQL はマニュアルが充実
http://clsql.b9.com/manual/index.html
      ここ読めば普通は困らないと思う
これだけだと
あまりにアレなので
いくつか Tips など
MySQL を使う場合

●   テーブル名の大文字 / 小文字区別問題
      ●   Linux 上で動作している MySQL はデフォルトでテーブル名の大文
            字と小文字を区別する ( 定義時の名前がそのまま使われる )
      ●   標準 SQL では区別しない
      ●   CLSQL は標準準拠 ( 基本的に大文字でサーバに送信する )



           テーブル名が見つからないと怒られる

●   /etc/mysql/my.cnf に以下を追加
      ●   追加場所 [mysqld] セクション
# for Case insensitive
lower_case_table_names          = 1

              詳細: http://dev.mysql.com/doc/refman/5.1/ja/identifier-case-sensitivity.html
connection オブジェクト
●   connect 関数
      ●   データベースへの接続オブジェクトを作成する
      ●   同じ属性の接続を複数作ろうとするとデフォルトではエラー!
      ●   :if­exists キーワード引数でどうするかを決める
          –   :new        新しく接続オブジェクトを作る
          –   :warn­new   警告出すけどオブジェクトを作る
          –   :error      エラーとする
          –   :old        すでに開いている接続オブジェクトを返す
          –   :warn­old   警告出して、既存の接続オブジェクトを返す
          –   デフォルト値は     *connect­if­exists* 変数で設定できる


●   connected-databases 関数
      ●   現時点で有効な全ての接続オブジェクトをリストで返す

●   *default-database* 変数
      ●   既定の接続オブジェクトを保持する
接続を切る

●   disconnect 関数を使う
      ●   :database キーワード引数で対象の接続オブジェクトを指定する
      ●   省略時は clsql:*default­database* が指定されたものとみ
           なされる

CL­USER> (defparameter db­conn nil)

CL­USER> (setf db­conn 
            (connect '("achernar" "stats_master" "xlisting" "xlisting")
               :database­type :mysql))

CL­USER> (eq db­conn *default­database*)

CL­USER> (disconnect :database db­conn)

CL­USER> *default­database*
SQL Quote の方法
●   SQL 関数を使えば簡単
CL­USER> (format nil "select * from foo where bar in ~a"
            (sql '("Hello" "world")))

CL­USER> (format nil "select * from foo where bar = ~a" 
            (sql " 波浪ワールド  'Hello World'"))

CL­USER> (enable­sql­reader­syntax)

CL­USER> (let ((msg "Hello 'lisp' world!"))
           (sql [select [foo] [bar] :from [baz] :where [= [name] msg]]))

CL­USER> (sql [select 
                [client_base name]
                [agency_base name]
                  :from '([client_base] [agency_base])
                  :where [= [client_base agency_id] [agency_base id]]])




          値の埋め込みは format 使うよりも SQL テンプレの方がお勧め
SQL テンプレ

●   Lisp の構文そのものが拡張されちゃうので注意
     ●   グローバルに有効化:   (enable-sql-reader-syntax)
     ●   グローバルに無効化:   (disable-sql-reader-syntax)
     ●   ローカルに有効化:    (locally-enable-sql-reader-syntax)
     ●   ローカルに無効化:    (locally-disable-sql-reader-syntax)

●   [ と ] に意味が追加されてる
     ●   Reader マクロという機能を使っている
取得した行について繰り返し処理

●   do-query とか loop フォームが便利
CL­USER> (do­query ((agency­name client­name)
                    (sql [select [agency_base name] [client_base name]
                      :from '([agency_base] [client_base])
                      :where [and [= [agency_base id] [client_base agency_id]]
                                  [= [agency_base id] 22]]]))
           (format t "~a : ~a~%" agency­name client­name))


CL­USER> (loop :for (agency­name client­name) being each tuple in 
                    (sql [select [agency_base name] [client_base name]
                      :from '([agency_base] [client_base])
                      :where [and [= [agency_base id] [client_base agency_id]]
                                  [= [agency_base id] 22]]])
            :do (format t "~a : ~a~%" agency­name client­name))


結果1行毎にガッツり処理したいとき                                 do-query
カウントしたりちょっと加工して収集しなおしたいとか                         loop

て感じで使い分けるといいかも。
まぁこのへんは好みというかソースが見やすくなるほうを優先するのが吉。
関数に仕立ててみる

●   こんな感じとか
(defun get­client­info­by­ids (ids)
  (let ((result nil))
    (multiple­value­bind (rows field­names)
        (query (sql [select [*] :from [client_base] :where [in [id] ids]]))
       
       (dolist (row rows)
         (push
           (loop :for value in row
                 :for field­name in field­names
                 :collect (cons field­name value)) result)))
    result))



CL­USER> (get­client­info­by­ids '(1 3 5))

CL­USER> (dolist (result (get­client­info­by­ids '(1 3 5)))
           (print (cdr (assoc "name" result :test #'string=))))
connection pool

●   こんな感じでやるといいかも
(defun get­client­info­by­ids (ids &key (database clsql:*default­database*))
  (let ((result nil))
    (multiple­value­bind (rows field­names)
        (query (sql [select [*] :from [client_base] :where [in [id] ids]])
                 :database database)
       (dolist (row rows)
         (push
          (loop :for value in row
             :for field­name in field­names
             :collect (cons field­name value)) result)))
    result))



(with­database
    (db­conn '("achernar" "stats_master" 
               "<user­name>" "<password>") :pool t :database­type :mysql)

           (get­client­info­by­ids '(1 2 3) :database db­conn))
create / drop table

●   ここでもテンプレ使えます
CL­USER> (create­table [test_table]
                       '(([id] integer :not­null :unique :primary­key)
                         ([name] (varchar 255) :not­null)
                         ([status] boolean :not­null)))


CL­USER> (table­exists­p [test_table])

CL­USER> (drop­table [test_table])

CL­USER> (table­exists­p [test_table])
insert / update / delete

●   それぞれ関数があるので使いましょう
CL­USER> (insert­records :into [test_table] 
                         :attribute '(id name status)
                         :values '(1 "James 'random' Hacker" 1))

CL­USER> (select [*] :from [test_table])

CL­USER> (update­records [test_table] 
                         :av­pairs '((name "foo bar")
                                     (status 0))
                         :where [= [id] 1])

CL­USER> (select [*] :from [test_table])

CL­USER> (delete­records :from [test_table] :where [= [name] "foo bar"])

CL­USER> (select [*] :from [test_table])
マニュアルをよく読むべし

    Lisp 系のマニュアルの書かれ方はちょっと独特だけど
CLSQL のマニュアルは例がいっぱいあるので大いに参考にしよう
宿題

前回の宿題掲示板のストレージを
   データベースにしてね

ちょこっと改造すれは OK のハズなので、簡単でしょ?

         connection pool を使って
 with­database フォームを使うのがお勧めかも

More Related Content

What's hot

社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)Iwana Chan
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsYoshifumi Kawai
 
Webサーバ勉強会03
Webサーバ勉強会03Webサーバ勉強会03
Webサーバ勉強会03oranie Narut
 
Ansibleで始めるサーバ管理勉強会(2014年10月1日)
Ansibleで始めるサーバ管理勉強会(2014年10月1日)Ansibleで始めるサーバ管理勉強会(2014年10月1日)
Ansibleで始めるサーバ管理勉強会(2014年10月1日)CLARA ONLINE, Inc.
 
Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Taro Hirose
 
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみるJJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみるKoichi Sakata
 
静的サイトどこにする?
静的サイトどこにする?静的サイトどこにする?
静的サイトどこにする?ogawatti
 
Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Kazuki Ohta
 
いまさら聞けないRake入門
いまさら聞けないRake入門いまさら聞けないRake入門
いまさら聞けないRake入門Tomoya Kawanishi
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編Miki Shimogai
 
Varnish 4.0 Release Party in Tokyo発表資料
Varnish 4.0 Release Party in Tokyo発表資料Varnish 4.0 Release Party in Tokyo発表資料
Varnish 4.0 Release Party in Tokyo発表資料Iwana Chan
 
VarnishではじめるESI
VarnishではじめるESIVarnishではじめるESI
VarnishではじめるESIIwana Chan
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Yoshifumi Kawai
 
Handlersocket etc. 20110906
Handlersocket etc. 20110906Handlersocket etc. 20110906
Handlersocket etc. 20110906akirahiguchi
 
Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅-
Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅- Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅-
Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅- Daisuke Ikeda
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングKohsuke Yuasa
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ信之 岩永
 

What's hot (20)

Fabric Essentials
Fabric EssentialsFabric Essentials
Fabric Essentials
 
Ansible入門
Ansible入門Ansible入門
Ansible入門
 
社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)社内勉強会資料(Varnish Module)
社内勉強会資料(Varnish Module)
 
C#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive ExtensionsC#次世代非同期処理概観 - Task vs Reactive Extensions
C#次世代非同期処理概観 - Task vs Reactive Extensions
 
Webサーバ勉強会03
Webサーバ勉強会03Webサーバ勉強会03
Webサーバ勉強会03
 
Ansibleで始めるサーバ管理勉強会(2014年10月1日)
Ansibleで始めるサーバ管理勉強会(2014年10月1日)Ansibleで始めるサーバ管理勉強会(2014年10月1日)
Ansibleで始めるサーバ管理勉強会(2014年10月1日)
 
Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)
 
Openresty
OpenrestyOpenresty
Openresty
 
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみるJJUG CCC 2017 Fall オレオレJVM言語を作ってみる
JJUG CCC 2017 Fall オレオレJVM言語を作ってみる
 
静的サイトどこにする?
静的サイトどこにする?静的サイトどこにする?
静的サイトどこにする?
 
Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方Google Perf Tools (tcmalloc) の使い方
Google Perf Tools (tcmalloc) の使い方
 
いまさら聞けないRake入門
いまさら聞けないRake入門いまさら聞けないRake入門
いまさら聞けないRake入門
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編
 
Varnish 4.0 Release Party in Tokyo発表資料
Varnish 4.0 Release Party in Tokyo発表資料Varnish 4.0 Release Party in Tokyo発表資料
Varnish 4.0 Release Party in Tokyo発表資料
 
VarnishではじめるESI
VarnishではじめるESIVarnishではじめるESI
VarnishではじめるESI
 
Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)Deep Dive async/await in Unity with UniTask(UniRx.Async)
Deep Dive async/await in Unity with UniTask(UniRx.Async)
 
Handlersocket etc. 20110906
Handlersocket etc. 20110906Handlersocket etc. 20110906
Handlersocket etc. 20110906
 
Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅-
Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅- Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅-
Serverspecを自分好みにアレンジ スクリーンショットで証跡保存を撲滅-
 
C++ マルチスレッドプログラミング
C++ マルチスレッドプログラミングC++ マルチスレッドプログラミング
C++ マルチスレッドプログラミング
 
async/await のしくみ
async/await のしくみasync/await のしくみ
async/await のしくみ
 

Similar to Lisp Tutorial for Pythonista : Day 4

SQLQL は GraphQL にとってなんなのか
SQLQL は GraphQL にとってなんなのかSQLQL は GraphQL にとってなんなのか
SQLQL は GraphQL にとってなんなのかyancya
 
とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)Kazuhiro Yoshikawa
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1Ryosuke IWANAGA
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lispirix_jp
 
PerlとSQLのいろいろ
PerlとSQLのいろいろPerlとSQLのいろいろ
PerlとSQLのいろいろTakuya Tsuchida
 
配布用Beginnerならきっと役立つmaster slave環境
配布用Beginnerならきっと役立つmaster slave環境配布用Beginnerならきっと役立つmaster slave環境
配布用Beginnerならきっと役立つmaster slave環境yut148atgmaildotcom
 
PostgreSQLのソース・ターゲットエンドポイントとしての利用
PostgreSQLのソース・ターゲットエンドポイントとしての利用PostgreSQLのソース・ターゲットエンドポイントとしての利用
PostgreSQLのソース・ターゲットエンドポイントとしての利用QlikPresalesJapan
 
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...Google Cloud Platform - Japan
 
MySQLを割と一人で300台管理する技術
MySQLを割と一人で300台管理する技術MySQLを割と一人で300台管理する技術
MySQLを割と一人で300台管理する技術yoku0825
 
LINEのMySQL運用について
LINEのMySQL運用についてLINEのMySQL運用について
LINEのMySQL運用についてLINE Corporation
 
activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介Kevin Toyoda
 
Handlersocket 20110517
Handlersocket 20110517Handlersocket 20110517
Handlersocket 20110517akirahiguchi
 
第8回KPF発表資料
第8回KPF発表資料第8回KPF発表資料
第8回KPF発表資料cryks
 
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 TokyoYoshiyuki Asaba
 

Similar to Lisp Tutorial for Pythonista : Day 4 (20)

SQLQL は GraphQL にとってなんなのか
SQLQL は GraphQL にとってなんなのかSQLQL は GraphQL にとってなんなのか
SQLQL は GraphQL にとってなんなのか
 
とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)とあるDBAの黒い画面(ターミナル)
とあるDBAの黒い画面(ターミナル)
 
tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1
 
OpenStack + Common Lisp
OpenStack + Common LispOpenStack + Common Lisp
OpenStack + Common Lisp
 
PerlとSQLのいろいろ
PerlとSQLのいろいろPerlとSQLのいろいろ
PerlとSQLのいろいろ
 
MoteMote Compiler Plugin
MoteMote Compiler PluginMoteMote Compiler Plugin
MoteMote Compiler Plugin
 
配布用Beginnerならきっと役立つmaster slave環境
配布用Beginnerならきっと役立つmaster slave環境配布用Beginnerならきっと役立つmaster slave環境
配布用Beginnerならきっと役立つmaster slave環境
 
MySQL SQL tuning
MySQL SQL tuningMySQL SQL tuning
MySQL SQL tuning
 
Slick入門
Slick入門Slick入門
Slick入門
 
キメるClojure
キメるClojureキメるClojure
キメるClojure
 
Mysql casial01
Mysql casial01Mysql casial01
Mysql casial01
 
PostgreSQLのソース・ターゲットエンドポイントとしての利用
PostgreSQLのソース・ターゲットエンドポイントとしての利用PostgreSQLのソース・ターゲットエンドポイントとしての利用
PostgreSQLのソース・ターゲットエンドポイントとしての利用
 
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...
アプリ開発者、DB 管理者視点での Cloud Spanner 活用方法 | 第 10 回 Google Cloud INSIDE Games & App...
 
MySQLを割と一人で300台管理する技術
MySQLを割と一人で300台管理する技術MySQLを割と一人で300台管理する技術
MySQLを割と一人で300台管理する技術
 
Slub data structure
Slub data structureSlub data structure
Slub data structure
 
LINEのMySQL運用について
LINEのMySQL運用についてLINEのMySQL運用について
LINEのMySQL運用について
 
activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介activerecord-oracle_enhanced-adapterのご紹介
activerecord-oracle_enhanced-adapterのご紹介
 
Handlersocket 20110517
Handlersocket 20110517Handlersocket 20110517
Handlersocket 20110517
 
第8回KPF発表資料
第8回KPF発表資料第8回KPF発表資料
第8回KPF発表資料
 
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
 

More from Ransui Iso

「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~Ransui Iso
 
Pythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクターPythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクターRansui Iso
 
アドテクを支える人と技術
アドテクを支える人と技術アドテクを支える人と技術
アドテクを支える人と技術Ransui Iso
 
Playing with curses
Playing with cursesPlaying with curses
Playing with cursesRansui Iso
 
小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話Ransui Iso
 
XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由Ransui Iso
 
ソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミングソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミングRansui Iso
 
Introduction of ToySynth
Introduction of ToySynthIntroduction of ToySynth
Introduction of ToySynthRansui Iso
 
PyQtではじめるGUIプログラミング
PyQtではじめるGUIプログラミングPyQtではじめるGUIプログラミング
PyQtではじめるGUIプログラミングRansui Iso
 
PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.Ransui Iso
 
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Ransui Iso
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Ransui Iso
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Ransui Iso
 

More from Ransui Iso (14)

「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~「Pythonでやってみた」~広がるプログラミングの愉しみ~
「Pythonでやってみた」~広がるプログラミングの愉しみ~
 
Pythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクターPythonで作る俺様サウンドエフェクター
Pythonで作る俺様サウンドエフェクター
 
アドテクを支える人と技術
アドテクを支える人と技術アドテクを支える人と技術
アドテクを支える人と技術
 
Playing with curses
Playing with cursesPlaying with curses
Playing with curses
 
小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話小中学生Hack-a-thonにオッサンが乗り込んだ話
小中学生Hack-a-thonにオッサンが乗り込んだ話
 
XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由XML-RPC : Pythonが「電池付属」と呼ばれる理由
XML-RPC : Pythonが「電池付属」と呼ばれる理由
 
ソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミングソフトシンセを作りながら学ぶPythonプログラミング
ソフトシンセを作りながら学ぶPythonプログラミング
 
Introduction of ToySynth
Introduction of ToySynthIntroduction of ToySynth
Introduction of ToySynth
 
PyQtではじめるGUIプログラミング
PyQtではじめるGUIプログラミングPyQtではじめるGUIプログラミング
PyQtではじめるGUIプログラミング
 
PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.PySynth : A toy pure python software synthesizer.
PySynth : A toy pure python software synthesizer.
 
Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5Lisp Tutorial for Pythonista : Day 5
Lisp Tutorial for Pythonista : Day 5
 
Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3Lisp Tutorial for Pythonista : Day 3
Lisp Tutorial for Pythonista : Day 3
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
 

Recently uploaded

論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 

Recently uploaded (9)

論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 

Lisp Tutorial for Pythonista : Day 4

  • 1. Lisp tutorial for Pythonista. Day #4 : Work with RDBMS Ransui Iso Strategic Technology Group, X-Listing Co, Ltd.
  • 3. 今日は予告通り SQL ! なんだかんだで RDBMS 使えないと 仕事では困っちゃう
  • 5. QuickLisp でインストール clsql と clsql­mysql と clsql­postgresql をインストールしてくださいませ
  • 6. REPL 環境下でテストしてみる ● とりあえず select CL­USER> (use­package :clsql) CL­USER> (connect '("achernar" "stats_master" "<user­name>" "<password>")              :database­type :mysql) #<CLSQL­MYSQL:MYSQL­DATABASE achernar/stats_master/<user­name> OPEN {100343DEE1}> CL­USER> (query "select id, client_id from campaign_base limit 2") ((1712 3736) (815 3371)) ("id" "client_id") ● 多値関数なので… CL­USER> (multiple­value­bind (rows field­names)              (query "select * from campaign_base limit 2")            (dolist (row rows)              (loop :for value :in row                    :for field­name :in field­names                    :do (format t "~a : ~a~%" field­name value))              (terpri))) (terpri) :標準出力に改行を送る関数
  • 7. プログラムで使う場合は ● 例によって asdf でロードする ● (asdf:oos 'asdf:load­op :clsql) (asdf:oos 'asdf:load­op :clsql­mysql) ● (asdf:oos 'asdf:load­op :clsql­postgresql) ● SLIME の REPL で使う時も手動でロードしとく ● Backend は使いたいやつだけで OK よ ● パッケージ名は clsql ● いちいちパッケージ名解決 (clsql:query ... ) とか面倒な人は (use­package :clsql) ● 個人的には use-package はあまりオススメしないけどね。 ● Python で言うところの from clsql import * だし…
  • 8. CLSQL はマニュアルが充実 http://clsql.b9.com/manual/index.html ここ読めば普通は困らないと思う
  • 10. MySQL を使う場合 ● テーブル名の大文字 / 小文字区別問題 ● Linux 上で動作している MySQL はデフォルトでテーブル名の大文 字と小文字を区別する ( 定義時の名前がそのまま使われる ) ● 標準 SQL では区別しない ● CLSQL は標準準拠 ( 基本的に大文字でサーバに送信する ) テーブル名が見つからないと怒られる ● /etc/mysql/my.cnf に以下を追加 ● 追加場所 [mysqld] セクション # for Case insensitive lower_case_table_names          = 1 詳細: http://dev.mysql.com/doc/refman/5.1/ja/identifier-case-sensitivity.html
  • 11. connection オブジェクト ● connect 関数 ● データベースへの接続オブジェクトを作成する ● 同じ属性の接続を複数作ろうとするとデフォルトではエラー! ● :if­exists キーワード引数でどうするかを決める – :new 新しく接続オブジェクトを作る – :warn­new 警告出すけどオブジェクトを作る – :error エラーとする – :old すでに開いている接続オブジェクトを返す – :warn­old 警告出して、既存の接続オブジェクトを返す – デフォルト値は *connect­if­exists* 変数で設定できる ● connected-databases 関数 ● 現時点で有効な全ての接続オブジェクトをリストで返す ● *default-database* 変数 ● 既定の接続オブジェクトを保持する
  • 12. 接続を切る ● disconnect 関数を使う ● :database キーワード引数で対象の接続オブジェクトを指定する ● 省略時は clsql:*default­database* が指定されたものとみ なされる CL­USER> (defparameter db­conn nil) CL­USER> (setf db­conn              (connect '("achernar" "stats_master" "xlisting" "xlisting")                :database­type :mysql)) CL­USER> (eq db­conn *default­database*) CL­USER> (disconnect :database db­conn) CL­USER> *default­database*
  • 13. SQL Quote の方法 ● SQL 関数を使えば簡単 CL­USER> (format nil "select * from foo where bar in ~a"             (sql '("Hello" "world"))) CL­USER> (format nil "select * from foo where bar = ~a"              (sql " 波浪ワールド  'Hello World'")) CL­USER> (enable­sql­reader­syntax) CL­USER> (let ((msg "Hello 'lisp' world!"))            (sql [select [foo] [bar] :from [baz] :where [= [name] msg]])) CL­USER> (sql [select                  [client_base name]                 [agency_base name]                   :from '([client_base] [agency_base])                   :where [= [client_base agency_id] [agency_base id]]]) 値の埋め込みは format 使うよりも SQL テンプレの方がお勧め
  • 14. SQL テンプレ ● Lisp の構文そのものが拡張されちゃうので注意 ● グローバルに有効化: (enable-sql-reader-syntax) ● グローバルに無効化: (disable-sql-reader-syntax) ● ローカルに有効化: (locally-enable-sql-reader-syntax) ● ローカルに無効化: (locally-disable-sql-reader-syntax) ● [ と ] に意味が追加されてる ● Reader マクロという機能を使っている
  • 15. 取得した行について繰り返し処理 ● do-query とか loop フォームが便利 CL­USER> (do­query ((agency­name client­name)                     (sql [select [agency_base name] [client_base name]                       :from '([agency_base] [client_base])                       :where [and [= [agency_base id] [client_base agency_id]]                                   [= [agency_base id] 22]]]))            (format t "~a : ~a~%" agency­name client­name)) CL­USER> (loop :for (agency­name client­name) being each tuple in                      (sql [select [agency_base name] [client_base name]                       :from '([agency_base] [client_base])                       :where [and [= [agency_base id] [client_base agency_id]]                                   [= [agency_base id] 22]]])             :do (format t "~a : ~a~%" agency­name client­name)) 結果1行毎にガッツり処理したいとき do-query カウントしたりちょっと加工して収集しなおしたいとか loop て感じで使い分けるといいかも。 まぁこのへんは好みというかソースが見やすくなるほうを優先するのが吉。
  • 16. 関数に仕立ててみる ● こんな感じとか (defun get­client­info­by­ids (ids)   (let ((result nil))     (multiple­value­bind (rows field­names)         (query (sql [select [*] :from [client_base] :where [in [id] ids]]))                (dolist (row rows)          (push            (loop :for value in row                  :for field­name in field­names                  :collect (cons field­name value)) result)))     result)) CL­USER> (get­client­info­by­ids '(1 3 5)) CL­USER> (dolist (result (get­client­info­by­ids '(1 3 5)))            (print (cdr (assoc "name" result :test #'string=))))
  • 17. connection pool ● こんな感じでやるといいかも (defun get­client­info­by­ids (ids &key (database clsql:*default­database*))   (let ((result nil))     (multiple­value­bind (rows field­names)         (query (sql [select [*] :from [client_base] :where [in [id] ids]])                  :database database)        (dolist (row rows)          (push           (loop :for value in row              :for field­name in field­names              :collect (cons field­name value)) result)))     result)) (with­database     (db­conn '("achernar" "stats_master"                 "<user­name>" "<password>") :pool t :database­type :mysql)            (get­client­info­by­ids '(1 2 3) :database db­conn))
  • 18. create / drop table ● ここでもテンプレ使えます CL­USER> (create­table [test_table]                        '(([id] integer :not­null :unique :primary­key)                          ([name] (varchar 255) :not­null)                          ([status] boolean :not­null))) CL­USER> (table­exists­p [test_table]) CL­USER> (drop­table [test_table]) CL­USER> (table­exists­p [test_table])
  • 19. insert / update / delete ● それぞれ関数があるので使いましょう CL­USER> (insert­records :into [test_table]                           :attribute '(id name status)                          :values '(1 "James 'random' Hacker" 1)) CL­USER> (select [*] :from [test_table]) CL­USER> (update­records [test_table]                           :av­pairs '((name "foo bar")                                      (status 0))                          :where [= [id] 1]) CL­USER> (select [*] :from [test_table]) CL­USER> (delete­records :from [test_table] :where [= [name] "foo bar"]) CL­USER> (select [*] :from [test_table])
  • 20. マニュアルをよく読むべし Lisp 系のマニュアルの書かれ方はちょっと独特だけど CLSQL のマニュアルは例がいっぱいあるので大いに参考にしよう
  • 21. 宿題 前回の宿題掲示板のストレージを データベースにしてね ちょこっと改造すれは OK のハズなので、簡単でしょ? connection pool を使って with­database フォームを使うのがお勧めかも