ラベル postgres の投稿を表示しています。 すべての投稿を表示
ラベル postgres の投稿を表示しています。 すべての投稿を表示

2016/07/28

serialのシーケンスがなが~い名前になる場合

<>PostgreSQLの serial はシーケンスを生成するわけだけども、シーケンスの名前は table_name_column_name_seq という形で生成される。users テーブルの id ならば users_id_seqという感じで

しかし、シーケンス名は63文字までなので、なが~い名前のテーブルのなが~い名前の列を対象にした場合は63文字を超えてしまう場合も当然あって、そんな場合は切り詰められたものが名前になる。 例えば long_long_name_table_abcd_efgh_ijkl_mnop_qrst_uvwx_yz テーブルの long_long_name_column_abcd_efgh_ijkl_mnop_qrst_uvwx_yz を対象にした場合は sample.long_long_name_table_abcd_efg_long_long_name_column_abcd_ef_seq となる。

このシーケンス名を取得するには pg_catalog.pg_get_serial_sequence 関数を使えばいいのだが、まあごくたまにはDBにアクセスせずにこのシーケンス名を指定したい場合があって、その場合は内部ルールをトレースする必要がある。

おそらく内部仕様はこんな感じ

  1. テーブル名と列名の長さが合わせて58文字以下ならそのまま作成
  2. テーブル名と列名ともに30文字以上ならばどちらも29文字に切り詰めて作成
  3. どちらかが29文字未満のばあい、短い方はそのまま使用し残りの分(58-短い方の文字数)を長い方から切り出して作成
jsで書くならこんな感じ。 この辺の仕様を説明した公式ドキュメントが無いかなと探してみたけど見つからない。ソース読むしか無いのだろうか

ちなみにこの結果、既存のシーケンスと名前が被るとき(例えば長い名前で末尾がほんの少しだけ違うテーブルのid列をserialで作成しようとした場合)は素直にエラーになってくれるので、名前を付け直すか integer で作って、シーケンスを別途作成しましょう。

2012/05/12

Ubuntu 12.04 に色々とアプリケーションをインストールした

Ubuntu 12.04 にいつもの環境を整えた。

環境系

# 日本語ディレクトリを英語に
$ LANG=C xdg-user-dirs-gtk-update

# aptitude はデフォルトではインストールされていない
$ sudo apt-get aptitude

# システムをアップデート
$ sudo aptitude update
$ sudo aptitude full-upgrade

# screen も入ってなかった
$ sudo aptitude install -y screen

# 日本語入力はmozc
$ sudo aptitude install -y ibus-mozc

# 日本語のほうがありがたい
$ sudo aptitude install -y manpages-ja

# シェルは zsh
$ sudo aptitude install -y zsh

# vim 必須
$ sudo aptitude install -y vim-nox vim-gnome

# lv 使う
$ sudo aptitude install -y lv

アプリケーション

# Google Chrome と Dropbox は本家からインストールする

# コマンドラインランチャ。これがあれば左側のいらない
$ sudo aptitude install -y gnome-do

# F12でターミナルが降りてくる。とても便利。zsh を使う際、bash をかませる必要がなくなった
$ sudo aptitude install -y guake

開発環境

# 開発するならこれは必須
$ sudo aptitude install -y build-essential

# webサーバは無難にapache
$ sudo aptitude install -y apache2

# DB は PostgreSQL(バージョンが9.1.3になってる)
$ sudo aptitude install -y postgresql libpq-dev pgadmin3

# Subversion から git に完全移行中なのであえて Subversion は入れない
$ sudo aptitude install -y git-core

# ライブラリのインストール(zlib1g-dev とか libssl-dev はすでに入ってたけど一応)
$ sudo aptitude install -y zlib1g-dev libssl-dev libreadline-dev libxslt-dev libxml2-dev libyaml-dev libsqlite3-dev

# rbenv を github から取得
$ mkdir ~/git_repos
$ cd ~/git_repos
$ git clone git://github.com/sstephenson/rbenv.git
$ cd ~
$ ln -s git_repos/rbenv .rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> .zshrc
$ echo 'eval "$(rbenv init -)"' >> .zshrc
$ source .zshrc

# ruby-build を github から取得
$ cd git_repos
$ git clone git://github.com/sstephenson/ruby-build.git
$ cd ruby-build
$ sudo sh install.sh

# 最新バージョンを確認して、最新をインストールして、使用するように設定する
$ rbenv install
$ rbenv install 1.9.3-p194
$ rbenv rehash
$ rbenv global 1.9.3-p194
Ruby on Rails 3.2 を Ubuntu にインストールする手順をかなり丁寧に説明してみました - Rails 雑感 - Ruby on Rails with OIAXとかを参照すると rbenv は apt で入れられるようになったみたいだが、自分の環境だとダメだった。
インストールはできるが、rbenv global しても /usr/bin/ruby が居座り続ける。
apt から rbenv をインストールすると ruby1.9.1(実体はruby1.9.3-p0)もインストールされる。
これが /usr/bin/ruby の実体になるので、rbenv global してから ruby -v すると、ruby1.9.3-p0 のまま。
ruby1.9.1 パッケージを削除しようとすると rbenv が依存しているため rbenv が動かなくなる。
どうにもならないので、全部削除して rbenv を github から取ってきたらうまくいった。

2012/04/29

さくら VPS の Ubuntu Server 10.04 に Redmine を導入

サーバの準備も整ったので、いよいよ使えるようにして行きましょう。
なにはさておき Redmine は入れておきたい!!
なので今回は Redmine の導入です。
いろいろダルかった。

Redmine の取得

Redmine をダウンロードして、配置します。
バージョンは最新の 1.4.1。Ruby 1.9 に対応してくれて本当によかった。
$ wget http://rubyforge.org/frs/download.php/76033/redmine-1.4.1.tar.gz
$ tar xvf redmine-1.4.1.tar.gz 
$ mkdir /var/lib/rails
$ mv redmine-1.4.1 /var/lib/rails/redmine

依存 gem のインストール

ここがダルかった。rmagick とか、rmagick とか、rmagick とか
$ cd /var/lib/rails/redmine
$ bundle install --path vendor/bundle --without development test mysql sqlite
  〜〜 省略 〜〜
Installing rmagick (2.13.1) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/local/ruby/bin/ruby extconf.rb 
checking for Ruby version >= 1.8.5... yes
extconf.rb:128: Use RbConfig instead of obsolete and deprecated Config.
checking for gcc... yes
checking for Magick-config... no
Can't install RMagick 2.13.1. Can't find Magick-config in /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  〜〜 省略 〜〜

# 失敗したので、libmagick-dev をインストールして ruby を再コンパイル
$ aptitude install libmagick-dev
$ cd ~/work/ruby-1.9.3-p194
$ ./configure --prefixe=/usr/local/ruby
$ make
$ make install

# 再トライ
$ bundle install --path vendor/bundle --without development test mysql sqlite
  〜〜 省略 〜〜
Installing rmagick (2.13.1) with native extensions
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

        /usr/local/ruby/bin/ruby extconf.rb 
checking for Ruby version >= 1.8.5... yes
extconf.rb:128: Use RbConfig instead of obsolete and deprecated Config.
checking for gcc... yes
checking for Magick-config... no
Can't install RMagick 2.13.1. Can't find Magick-config in /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  〜〜 省略 〜〜
checking for Magick-config... yes
checking for ImageMagick version >= 6.4.9... no
Can't install RMagick 2.13.1. You must have ImageMagick 6.4.9 or later.
  〜〜 省略 〜〜

# インストール済みの ImageMagic のバージョンが古いとのこと
# 仕方ないので最新をソースからインストールする
$ cd ~/work
$ wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick-6.7.6-7.tar.gz
$ tar xvf ImageMagick-6.7.6-7.tar.gz
$ cd ImageMagick-6.7.6-7
$ ./configure --enable-lzw=yes
$ make
$ make install
# 確認
$ convert --version
Version: ImageMagick 6.7.6-7 2012-04-29 Q16 http://www.imagemagick.org

# 今度こそ
$ bundle install --path vendor/bundle --without development test mysql sqlite
  〜〜 省略 〜〜
Installing rmagick (2.13.1) with native extensions
  〜〜 省略 〜〜
Your bundle is complete! It was installed into ./vendor/bundle
結局は、ソースから ImageMagick をインストールする必要があるということですね。

データベースの設定(PostgreSQL 8.4)

# Redmine 用ユーザーを作成
$ su - postgres
$ psql
postgres=# create role redmine_user with login 'password';
postgres=# \q

# Redmine のデータベースを作成
$ createdb redmine --encoding=UTF-8 --locale=ja_JP.UTF-8
createdb: database creation failed: ERROR:  新しい照合順序(ja_JP.UTF-8)はテンプレートデータベースの照合順序(en_US.UTF-8)と互換性がありません
HINT:  テンプレートデータベースの照合順序と同じものを使うか、もしくは template0 をテンプレートとして使用してください
# 怒られたので、HINT に従う
$ createdb redmine --encoding=UTF-8 --locale=ja_JP.UTF-8 --template=template0

# root に戻る
$ exit
$ cd /var/lib/rails/redmine

# データベース接続設定ファイルを作成
$ cp config/database.yml.example config/database.yml
$ vim config/database.yml
  production:
-   adapter: mysql
+   adapter: postgresql
    database: redmine
    host: localhost
-   username: root
+   username: redmine_user
-   password:
+   password: password
    encoding: utf8

# セッションストアの生成
$ bundle exec rake -- generate_session_store
# マイグレーション実行
$ bundle exec rake db:migrate RAILS_ENV=production
# デフォルトデータ登録(言語選択あり)
$ bundle exec rake redmine:load_default_data RAILS_ENV=production
Select language: ar, bg, bs, ca, cs, da, de, el, en, en-GB, es, et, eu, fa, fi, fr, gl, he, hr, hu, id, it, ja, ko, lt, lv, mk, mn, nl, no, pl, pt, pt-BR, ro, ru, sk, sl, sr, sr-YU, sv, th, tr, uk, vi, zh, zh-TW [en] ja # ←入力して Enter
====================================
Default configuration data loaded.

Apache 設定

今回はバーチャルホストでの運用にします。
DNS の設定が必要だけど。
$ cd /etc/apache2
$ vim sites-available/redimne
<VirtualHost *:80>
    ServerName xxx.mkt-sys.jp
    DocumentRoot /var/lib/rails/redmine/public
    PassengerEnabled on
</VirtualHost>

$ cd sites-enabled
$ ln - ../sites-available/redmine 001-redmine
# root だとログファイルの書き出しとかでエラーになる
$ chown -R www-data:www-data /var/lib/rails/redmine
$ service apache2 restart

ログをローテーションさせる

$ vim /etc/logrotate.d/redmine
/var/lib/rails/redmine/log/*log {
  weekly
  missingok
  notifempty
  copytruncate
}

確認

http://xxx.mkt-sys.jp にアクセス。
無事表示された。お疲れ様でした。

さくら VPS (Ubuntu Server 10.04)設定エントリ一覧

2012/04/28

さくら VPS の Ubuntu Server 10.04 にて PostgreSQL の設定

tail -f pinzo.log: ubuntu 10.04 に rails 開発環境を作る - PostgreSQL 設定編の焼き直し+α

postgres ユーザのパスワード設定

# postgres ユーザのパスワードを設定
$ passwd postgres

# postgres ユーザに su して(これ以降は、基本的に postgres ユーザで作業)
$ su - postgres

# PostgreSQL 側のパスワードを一致させる
$ psql template1
template1 =# alter user postgres with password '12345';
template1 =# \q

rails 用ユーザの作成

$ psql
postgres =# create role rails_user with login password '98765';
postgres =# \q

pg_hba.conf の編集

# root に戻る
$ exit

# pg_hba.conf を編集
$ vi /etc/postgresql/8.4/main/pg_hba.conf
- local all all ident + local all all password

日本語設定

$ vi /etc/postgresql/8.4/main/postgresql.conf
# These settings are initialized by initdb, but they can be changed. - lc_messages = 'en_US.UTF-8' # locale for system error message - lc_monetary = 'en_US.UTF-8' # locale for monetary formatting - lc_numeric = 'en_US.UTF-8' # locale for number formatting - lc_time = 'ja_JP.UTF-8' # locale for time formatting + lc_messages = 'ja_JP.UTF-8' # locale for system error message + lc_monetary = 'ja_JP.UTF-8' # locale for monetary formatting + lc_numeric = 'ja_JP.UTF-8' # locale for number formatting + lc_time = 'ja_JP.UTF-8' # locale for time formatting # default configuration for text search - default_text_search_config = 'pg_catalog.english' + default_text_search_config = 'pg_catalog.japanese'

サービス再起動

$ service postgresql-8.4 restart

さくら VPS (Ubuntu Server 10.04)設定エントリ一覧

2012/02/07

PostgreSQL の interval (と reltime)

PostgreSQL にて n ヶ月後の初日や最終日を文字列で返す関数を登録しようとした。
イメージとしてはこんな感じ。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_date + interval '$1 months'), 'YYYY/MM/DD')$BODY$
language 'sql';
だがこれだとうまくいかなくて、引数に何を与えても 2012/03/01 が返ってくる。
'$1 months' が '1 months' とみなされている気がする。

で、次にやってみたのがこんな感じ。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_date + interval ($1 || ' months')), 'YYYY/MM/DD')$BODY$
language 'sql';
構文エラーで登録すらできない。

interval だとだめなのかなと思って、interval のいらない current_timestamp で挑戦してみる。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + ($1 || ' months')), 'YYYY/MM/DD')$BODY$
language 'sql';
「ERROR: 演算子が存在しません: date + text」と言われる。

なるほど text だからキャストが必要なのかと言うことで varchar にキャストしてみる。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as varchar)), 'YYYY/MM/DD')$BODY$
language 'sql';
これまた演算子が存在しないと言われる。

そういや、そもそも interval ってなんなんだ
と思って調べてみるとどうやらデータ型らしい。
interval '1 months' みたいに書くから識別子とかかと思ってたらデータ型でキャストというか型変換を意味していたのか!
というわけでこうしてみた。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as interval)), 'YYYY/MM/DD')$BODY$
language 'sql';
登録できたよ。
select first_date_string_on_month(3)
--  → 2012/05/01
select first_date_string_on_month(-2)
--  → 2011/12/01
select first_date_string_on_month(0)
--  → 2012/02/01
ちゃんと動いてるよ。

ちなみに reltime というデータ型もあるみたい。
create or replace function first_date_string_on_month(integer)
returns varchar
as 
$BODY$select to_char(date_trunc('month', current_timestamp + cast($1 || ' months' as reltime)), 'YYYY/MM/DD')$BODY$
language 'sql';
とすると登録できて同じ結果が取得できた。
reltime型 を引数に取る interval 関数というのがあるので、それが関係していると思われるがよくわからない。
Google 先生で調べても PostgreSQL と realtime の検索結果が表示されるし。
とりあえず interval を使うのが正当だと思うのでそれでいいや。

2010/11/05

gem install pg がエラーではまった

先ほどのエントリにて Thinkpad の環境構築時に唯一はまった点。
gem 以外の環境構築ができたので、rails アプリを svn で持ってきて bundle install した。
Building native extensions.  This could take a while...
ERROR:  Error installing pg:
        ERROR: Failed to build gem native extension.

/home/pinzolo/.rvm/rubies/ruby-1.8.7-p302/bin/ruby extconf.rb
checking for pg_config... yes 
checking for libpq-fe.h... yes 
checking for libpq/libpq-fs.h... yes 
checking for PQconnectdb() in -lpq... no 
checking for PQconnectdb() in -llibpq... no 
checking for PQconnectdb() in -lms/libpq... no 
Can't find the PostgreSQL client library (libpq) 
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of 
necessary libraries and/or headers.  Check the mkmf.log file for more 
details.  You may need configuration options. 

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/home/pinzolo/.rvm/rubies/ruby-1.8.7-p302/bin/ruby
        --with-pg
        --without-pg
        --with-pg-config
        --without-pg-config
        --with-pg-dir
        --without-pg-dir
        --with-pg-include
        --without-pg-include=${pg-dir}/include
        --with-pg-lib
        --without-pg-lib=${pg-dir}/lib
        --enable-static-build
        --disable-static-build

Gem files will remain installed in /home/pinzolo/.rvm/rubies/ruby-1.8.7-p302/gems/pg-0.9.0 for inspection.
Results logged to /home/pinzolo/.rvm/rubies/ruby-1.8.7-p302/gems/pg-0.9.0/ext/gem_make.out
いくつか調べたが、ずばりな解は見つからなかった。
要するにライブラリが見つからないんだろうと言うことで、
gem install pg -- --with-pq-config=/usr/lib/postgresql/8.4/bin --with-pg-lib=/usr/lib
てやったらインストールできた。めでたしめでたし。
ここまでが昨日。

でもよく考えたら pg_config って /usr/lib/postgresql/8.4/bin にはない。
てことは --with-pg-config=/usr/lib/postgresql/8.4/bin はおかしいんじゃないのか?
というわけで、いったん pg をアンインストールして、今度は下記を実行。
gem install pg -- --with-pg-lib=/usr/lib
おお、インストールできた。というわけで gem install pg -- --with-pg-lib=/usr/lib が正解です。
/usr/lib なんて参照のためにあるような場所なのに見てくれてないのか・・・

2010/05/15

ubuntu 10.04 に rails 開発環境を作る - PostgreSQL 設定編

rails から PostgreSQL にアクセスできる設定を行う。
まず、pgadmin からアクセスできるようにしよう。
デフォルトでは postgres ユーザのパスワードが分からないので、パスワードを設定する。
sudo passwd postgres で好きなパスワードを設定する。(今回は仮に12345とする)
次に su - postgres で postgres ユーザになり、PostgreSQL にログインする。
$ psql template1
template1 =# alter user postgres with password '12345';
template1 =# \q
つまり、パスワードを合わせておくということ。
これで pgadmin を立ち上げると postgres ユーザとして localhost のサーバを登録できるはず。

せっかくなので、ここでデータベースとログインロールを作っておこう。
pgadmin から GUI で作ることもできる。(割愛)
postgres ユーザで psql でログイン。
psql =# createdb test;
psql =# create role rails with login password '98765';
psql =# \q

先に rails のプロジェクトも作っておこう。
$ rails test -d postgresql

database.yml を変更しておこう。
development:
  adapter: postgresql
  encoding: utf8
  database: test
  pool: 5
  username: rails
  password: 98765

次に pg_hba.conf を修正する。
ファイルは /etc/postgresql/8.4/main/pg_hba.conf  にあった。
見つからない場合、sudo find / "pg_hba.conf" -type f でもやってみよう。
sudo vim /etc/postgresql/8.4/main/pg_hba.conf  と vim を起動する。
すると下記のような設定になっていた。
# Database administrative login by UNIX sockets
local   all         postgres                          ident
# "local" is for Unix domain socket connections only
local   all         all                               ident
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5
# IPv6 local connections:
host    all         all         ::1/128               md5
このままではパスワードでログインできないので、パスワードでログインできるように設定する。
で、ここでハマった。
事前調査の結果、"rails では TCP socket でアクセスするので、local じゃなくて host を変更する"と認識していた。
#host    all         all         127.0.0.1/32          md5
host    all         all         127.0.0.1/32          password
と変更すればいい、って情報があったのでこの一行を編集し PostgreSQL を再起動した。
$ sudo /etc/init.d/postgresql-8.4 restart
しかし、マイグレーションが失敗する。
手動でテーブル作って、script/console からデータの登録や取得をしようとしても失敗する。
で、悩みつつあれこれトライ&エラーを繰り返してみた結果、結局こういうことだった。
・database.yml で host: localhost 設定がされていれば、TCP socket を使用する。
・host: localhost 設定がされていない(host 設定がない)場合、UNIX socket を使用する。
つまり、デフォルトで作られた設定ファイルには  host 設定がなかったので、
local   all         all                               ident
の設定で接続しようとしていた。
#local   all         all                               ident
local   all         all                               password
と変更してやると、接続できマイグレーションも実行できた。

しかし、開発環境は別にどちらでもいいが、本番などは外部サーバにアクセスすることも多々あるし、一律 TCP での設定にしておいたほうがいいかなーと思ったので、database.yml に host: localhost の設定を追加して、host 設定の方を password にすることにした。

これで、rails から PostgreSQL に接続する設定(+α)は終了。