@luzluna - luz + luna
간단히 DB를 사용할 수 있는 모듈인 DBIx::Simple을 소개합니다.
데비안 계열의 리눅스를 사용하고 있다면 다음 명령을 이용해서 개발 의존 패키지를 설치합니다.
1 | $ sudo apt-get install libpq-dev |
필요한 모듈은 다음과 같습니다.
직접 CPAN을 이용해서 설치한다면 다음 명령을 이용해서 모듈을 설치합니다.
1 2 3 4 5 6 | $ sudo cpan \ DBD::Pg \ DBIx::Simple \ Data::Dump \ File::Slurp \ Mojolicious |
사용자 계정으로 모듈을 설치하는 방법을 정확하게 알고 있거나 perlbrew를 이용해서 자신만의 Perl을 사용하고 있다면 다음 명령을 이용해서 모듈을 설치합니다.
1 2 3 4 5 6 | $ cpan \ DBD::Pg \ DBIx::Simple \ Data::Dump \ File::Slurp \ Mojolicious |
PostgreSQL 데이터베이스를 기준으로 데이터베이스를 준비합니다.
데이터베이스에 접속하는 명령은 다음과 같습니다.
1 2 3 | $ psql -U postgres psql (9.3beta2) Type "help" for help. |
사용자 test
를 생성하고 비밀번호를 test$$
로 설정하는 명령은 다음과 같습니다.
1 2 | postgres=# CREATE USER test WITH PASSWORD 'test$$'; CREATE ROLE |
test
데이터베이스 생성합니다.
1 2 | postgres=# CREATE DATABASE test; CREATE DATABASE |
생성한 유저에게 접근 권한 부여합니다.
1 2 | postgres=# GRANT ALL PRIVILEGES ON DATABASE test to test; GRANT |
완료되었습니다. 프로그램을 종료하려면 다음 명령을 입력합니다.
1 2 | postgres=# \q $ |
테이블을 생성하기 위해 test
계정으로 test
데이터베이스에 접속합니다.
1 2 3 | $ psql -U test test psql (9.3beta2) Type "help" for help. |
postgres 9.3이후 디폴트로 포함된 데이터타입인 JSON 타입으로 데이터 필드를 선언해보았습니다.
내부적으로 TEXT
타입과 같지만 타입 체크 및 요소별 접근이 가능하고
특정 요소에 인덱스를 걸 수 있어서 NOSQL처럼 사용할 수 있다는 장점이 있습니다.
1 2 | test=> CREATE TABLE item ( id SERIAL PRIMARY KEY, data JSON ); CREATE TABLE |
샘플 자료를 추가해보죠.
1 2 | test=> INSERT INTO item (data) VALUES ('{"name":"test1", "value":31}'); INSERT 0 1 |
Mojolicious는 기본적으로 설정 파일을 지원합니다.
Mojolicious::Lite
를 이용해서 웹 응용을 제작할 경우 웹 응용과
동일한 파일명에 확장자를 .conf
로 설정하면 자동으로 읽어들입니다.
파일을 준비해보죠.
1 2 3 4 | $ mkdir dbix-simple-example $ cd dbix-simple-example $ touch item.conf $ touch item.pl |
item.conf
파일을 다음처럼 작성합니다.
1 2 3 4 5 6 7 | { db => [ 'dbi:Pg:dbname=test;host=127.0.0.1;port=5432' , 'test' , 'test$$' , ] } |
item.pl
파일을 다음처럼 작성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #!/usr/bin/env perl use Mojolicious::Lite; use DBD::Pg; use DBI; use DBIx::Simple; use JSON; my $config = plugin Config; my $dbh = DBIx::Simple-> connect ( @{ $config ->{db}} ); helper db => sub { $dbh }; get '/item/list' => sub { my $self = shift ; my $items = $self ->db->query( "SELECT * FROM item" )->hashes; for my $item (@ $items ) { $item ->{data} = JSON::decode_json( $item ->{data} ); } $self ->render( json => $items ); }; app; |
실행하는 명령은 다음과 같습니다.
1 2 3 4 | $ morbo -l http: // *:5000 item.pl [Mon Dec 9 18:15:17 2013] [debug] Reading config file "/home/user/dev/dbix_simple/config.conf" . Server available at http: //127 .0.0.1:5000. |
-l http://*:5000
옵션을 이용해 5000
번 포트로 실행했으므로
웹 브라우저로 접속할 때도 http://localhost:5000
주소로 접속해야 합니다.
웹 브라우저로 http://localhost:5000/item/list
주소로 접속해보세요.
1 | [{"id":1,"data":{"value":31,"name":"test1"}}] |
예쁘게 잘 나옵니다. :)
item.pl
웹 응용 코드의 app;
바로 위에 다음 코드를 추가합니다.
1 2 3 4 5 6 7 8 9 10 11 | get '/item/create' => 'item/create' ; post '/item/create' => sub { my $self = shift ; $self ->db->query( "INSERT INTO item (data) VALUES (?)" , $self ->param( 'data' ), ); $self ->render(json => { "status" => "done" }); }; |
그리고 item.pl
의 app;
바로 다음에 다음 코드를 추가합니다.
1 2 3 4 5 6 7 | __DATA__ @@ item/create.html.ep <form action= "/item/create" method= "post" > <input name= "data" type= "text" > <input type= "submit" > </form> |
morbo
는 변경한 소스를 자동으로 감지해서 새로 서버를 기동시키므로
별도로 종료 후 다시 기동할 필요는 없습니다.
이제 웹브라우저를 이용해서 http://localhost:5000/item/create
주소로 접속해보면
아이템을 추가하기 위한 간단한 양식을 볼 수 있습니다.
양식에 JSON 형식을 입력하면 다음과 같은 결과를 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 | # # 입력 # {"babo":"eee"} # # 결과 # {"status":"done"} |
유효하지 않은 JSON 형식을 입력할 경우의 PostgreSQL에서 발생하는 오류를 확인할 수 있습니다.
1 2 3 4 5 6 7 8 9 | # # 입력 # bad json format # # 결과 # DBD::Pg::st execute failed: ERROR: invalid input syntax for type json |
웹 페이지를 통하지 않고 일반 명령줄 유틸리티에서도 간단히 사용할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $!/usr/bin/env perl use v5.14; use strict; use warnings; use DBIx::Simple; use Data::Dump qw( dump ); use File::Slurp; my $config = eval ( read_file( 'config.conf' ) ); my $dbh = DBIx::Simple-> connect ( @{ $config ->{db}} ); my $ret = $dbh ->query( "SELECT * FROM item" )->hashes; say dump ( $ret ); |
실행한 결과는 다음과 같습니다.
1 2 3 4 5 | $ perl dbis.pl [ { data => "{\"name\":\"test1\", \"value\":31}" , id => 1 }, { data => "{\"babo\":\"eee\"}" , id => 2 }, ] |
웹페이지를 만드는 용도로 사용한다면 DBIx::XHTML_Table 모듈을 이용해서 테이블로 그려 볼수도 있고, 명령줄에서 사용한다면 Text::Table을 사용해 예쁘게 출력해볼 수도 있습니다. 이 부분은 과제로 남겨두죠. :)
Mojolicious나 Dancer 같은 경량 웹프레임워크를 사용하다보면 DBIx::Class 모듈이 조금 무겁게 느껴질 때가 있습니다. 그렇다고 그냥 DBI 모듈로 직접 쿼리를 날리는 것은 불편하구요. 이런때에 간단히 DBIx::Simple 모듈을 이용해보는건 어떨까요? ;-)
Artwork by
@namanvara,
Hyungsuk Hong
& Inkyung Park.
Designed by
Hojung Youn
& Keedi Kim.
Articles by
Seoul Perl Mongers.
Edited by
Keedi Kim.
Hosting generously sponsored by
Yuni Kim.
Sponsored by
SILEX.
.-''' __ __ / \/ \/ \ =-_- | \. -____- / \ // /|| '' //| //|| == = == ==