@luzluna - luz + luna
간단히 DB를 사용할 수 있는 모듈인 DBIx::Simple을 소개합니다.
데비안 계열의 리눅스를 사용하고 있다면 다음 명령을 이용해서 개발 의존 패키지를 설치합니다.
$ sudo apt-get install libpq-dev
필요한 모듈은 다음과 같습니다.
직접 CPAN을 이용해서 설치한다면 다음 명령을 이용해서 모듈을 설치합니다.
$ sudo cpan \ DBD::Pg \ DBIx::Simple \ Data::Dump \ File::Slurp \ Mojolicious
사용자 계정으로 모듈을 설치하는 방법을 정확하게 알고 있거나 perlbrew를 이용해서 자신만의 Perl을 사용하고 있다면 다음 명령을 이용해서 모듈을 설치합니다.
$ cpan \ DBD::Pg \ DBIx::Simple \ Data::Dump \ File::Slurp \ Mojolicious
PostgreSQL 데이터베이스를 기준으로 데이터베이스를 준비합니다.
데이터베이스에 접속하는 명령은 다음과 같습니다.
$ psql -U postgres psql (9.3beta2) Type "help" for help.
사용자 test
를 생성하고 비밀번호를 test$$
로 설정하는 명령은 다음과 같습니다.
postgres=# CREATE USER test WITH PASSWORD 'test$$'; CREATE ROLE
test
데이터베이스 생성합니다.
postgres=# CREATE DATABASE test; CREATE DATABASE
생성한 유저에게 접근 권한 부여합니다.
postgres=# GRANT ALL PRIVILEGES ON DATABASE test to test; GRANT
완료되었습니다. 프로그램을 종료하려면 다음 명령을 입력합니다.
postgres=# \q $
테이블을 생성하기 위해 test
계정으로 test
데이터베이스에 접속합니다.
$ psql -U test test psql (9.3beta2) Type "help" for help.
postgres 9.3이후 디폴트로 포함된 데이터타입인 JSON 타입으로 데이터 필드를 선언해보았습니다.
내부적으로 TEXT
타입과 같지만 타입 체크 및 요소별 접근이 가능하고
특정 요소에 인덱스를 걸 수 있어서 NOSQL처럼 사용할 수 있다는 장점이 있습니다.
test=> CREATE TABLE item ( id SERIAL PRIMARY KEY, data JSON ); CREATE TABLE
샘플 자료를 추가해보죠.
test=> INSERT INTO item (data) VALUES ('{"name":"test1", "value":31}'); INSERT 0 1
Mojolicious는 기본적으로 설정 파일을 지원합니다.
Mojolicious::Lite
를 이용해서 웹 응용을 제작할 경우 웹 응용과
동일한 파일명에 확장자를 .conf
로 설정하면 자동으로 읽어들입니다.
파일을 준비해보죠.
$ mkdir dbix-simple-example $ cd dbix-simple-example $ touch item.conf $ touch item.pl
item.conf
파일을 다음처럼 작성합니다.
{ db => [ 'dbi:Pg:dbname=test;host=127.0.0.1;port=5432', 'test', 'test$$', ] }
item.pl
파일을 다음처럼 작성합니다.
#!/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;
실행하는 명령은 다음과 같습니다.
$ morbo -l http://*:5000 item.pl [Mon Dec 9 18:15:17 2013] [debug] Reading config file "/home/user/dev/dbix_simple/config.conf". [Mon Dec 9 18:15:17 2013] [info] Listening at "http://*:5000". Server available at http://127.0.0.1:5000.
-l http://*:5000
옵션을 이용해 5000
번 포트로 실행했으므로
웹 브라우저로 접속할 때도 http://localhost:5000
주소로 접속해야 합니다.
웹 브라우저로 http://localhost:5000/item/list
주소로 접속해보세요.
[{"id":1,"data":{"value":31,"name":"test1"}}]
예쁘게 잘 나옵니다. :)
item.pl
웹 응용 코드의 app;
바로 위에 다음 코드를 추가합니다.
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;
바로 다음에 다음 코드를 추가합니다.
__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 형식을 입력하면 다음과 같은 결과를 확인할 수 있습니다.
# # 입력 # {"babo":"eee"} # # 결과 # {"status":"done"}
유효하지 않은 JSON 형식을 입력할 경우의 PostgreSQL에서 발생하는 오류를 확인할 수 있습니다.
# # 입력 # bad json format # # 결과 # DBD::Pg::st execute failed: ERROR: invalid input syntax for type json
웹 페이지를 통하지 않고 일반 명령줄 유틸리티에서도 간단히 사용할 수 있습니다.
$!/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);
실행한 결과는 다음과 같습니다.
$ 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.
.-''' __ __ / \/ \/ \ =-_- | \. -____- / \ // /|| '' //| //|| == = == ==