tech-memo

How to use PostgreSQL

install for mac

サーバ起動

正式は

su postgres pg_ctl start -D [データファイル]

Macの場合は、/Library/LaunchDaemonsに以下で入っている

/Library/PostgreSQL/14/bin/postmaster -D /Library/PostgreSQL/14/data

実際はpostgresユーザで起動しなければいけないためコマンドラインで、バックグラウンド起動するなら以下.

su postgres -c '/Library/PostgreSQL/14/bin/postmaster -D /Library/PostgreSQL/14/data >/tmp/postgres-log 2>&1 &'

サーバ停止

Linux系はKillでいいらしい

kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`

Macの場合、パスは /Library/PostgreSQL/14/data/postmaster.pid

pg_ctlでも落とせるが、自分のMacでは以下は効かない

su postgres pg_ctl stop -D

psqlの起動

sudo /Library/PostgreSQL/14/bin/psql -U postgres

install for linux

sudo apt-get install postgresql  
systemctl status postgresql.service
systemctl restart postgresql.service
sudo -u postgres psql  
create role ubuntu LOGIN;  
psql -d postgres  
alter user postgres PASSWORD '新しいパスワード'
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local all all peer

peerはOS認証でのログインのみ許すという意味なので、パスワード認証を許すmd5にする
変更したらサービス再起動と、パスワードファイルの作成(下に記載)

sqlファイルの実行

psql>\i [sqlファイル]
psql -U postgres < [ファイル名]

カラムの表示

postgresバックアップ

pg_dump -U postgres > backup.sql

sqlがそのまま吐かれる

バックアップ&リストア

主にオブジェクトをすべて上書きする場合.

pg_dump -U postgres -w -c --if-exists | gzip > [ファイル名]
psql -U postgres < [ファイル名]

パスワードファイル

# hostname:port:database:username:password
*:*:*:*:[パスワード]
chmod 0600 .pgpass

ログファイル

CSVファイルに出力

psql -U postgres -c "select product_id, title from movie;" -A -F, > movie_title_2.csv
psql -U postgres -c "COPY (select * from maker where id > ??) TO STDOUT WITH (FORMAT csv, HEADER false)" >  maker.tsv

これだと次のcopyコマンドでそのままインポートできる

CSVファイルをインポート

SQLで実行

COPY maker FROM '/tmp/maker.tsv' WITH (FORMAT 'csv', DELIMITER E'\t', NULL '');

実行されたSQLをログに吐き出す(performance monitorっぽいやつ)

ALTER SYSTEM SET log_statement = 'all';
SELECT pg_reload_conf();

SQL Tips

システムカタログ

psql>\dt
psql>\d [テーブル名]

cast

cast(hoge as numeric)
cast(hoge as character varying)

getdate()

select current_date;
select current_timestamp;

Truncate table

truncate table [テーブル名] RESTART IDENTITY CASCADE;

RESTRICT : 外部キー制約がある場合は削除しない. ←デフォルト
CASCADE : 外部キーを持つテーブルまで合わせて削除.
CONTINUE IDENTITY : シーケンスを戻さない. ←デフォルト
RESTART IDENTITY : シーケンスを戻す.

Drop table

ドロップも同様に外部キーがある場合はcascadeの指定が必要.
(外部キー指定がある場合、cascade未指定はdropが拒否される)

Auto Number型

create table tab1 (  
auto_no serial ,
...
create sequence next_movies_id_seq start with 1;
CREATE TABLE IF NOT EXISTS public.next_movies (
id bigint NOT NULL DEFAULT nextval('next_movies_id_seq'::regclass),
...

sequenceのリセット

select currval('actresses_id_seq');
select setval('actresses_id_seq', (select max(id) from actresses));

副問合せで更新

update a set col1 = b.col2 from tab1 a join tab2 b on a.col3 = b.col3 where ...

と書くやつは、

update tab1 set col1 = b.col2 from tab2 b where tab1.col3 = b.col3 where ...

と書く.

テーブルバックアップ

select * into table1_bak from table1

と書くやつは、

create table table1_bak as select * from table1;

と書く.

random select

where random() < 0.01 limit N

または

ORDER BY random() LIMIT 1;

order by でやるならwhere id = (select id ... order by random() limit 1などで主キーのみにした方がまだマシ

select * from [table] tablesample system_rows(N)
CREATE EXTENSION tsm_system_rows;

ただし、少数レコードには効かない

SYSTEM_ROWSはブロックレベルのサンプリングを行うため、サンプルは完全にはランダムではなく、特にごく少数の行が要求されたときはクラスタリングの影響を受けます。

正規表現で置換

update movie set  title = regexp_replace(title, '【MGS[^】]+】', '')  where title like '%【MGS%';

pythonでのpsycopg2を使った接続文字列

import psycopg2
DSN = 'dbname=postgres user=postgres'
con = psycopg2.connect(DSN)
DSN = 'dbname=postgres user=postgres host=/tmp/'

socketの調べ方

/etc/postgres/(バージョン番号)/main/postgresql.conf ファイルの中のunix_socket_directoriesにパスが書いてある