Install
- Ubuntu
# client
sudo apt-get install postgresql-client
# server
sudo apt-get install postgresql
- CentOS
wget --no-check-certificate https://yum.postgresql.org/10/redhat/rhel-7-x86_64/postgresql10-libs-10.19-1PGDG.rhel7.x86_64.rpm
wget --no-check-certificate https://yum.postgresql.org/10/redhat/rhel-7-x86_64/postgresql10-10.19-1PGDG.rhel7.x86_64.rpm
wget --no-check-certificate https://yum.postgresql.org/10/redhat/rhel-7-x86_64/postgresql10-server-10.19-1PGDG.rhel7.x86_64.rpm
sudo yum install postgresql10-libs-10.19-1PGDG.rhel7.x86_64.rpm
sudo yum install postgresql10-10.19-1PGDG.rhel7.x86_64.rpm
sudo yum install postgresql10-server-10.19-1PGDG.rhel7.x86_64.rpm
sudo /usr/pgsql-10/bin/postgresql-10-setup initdb
sudo systemctl start postgresql-10
sudo systemctl status postgresql-10
这时必须要切换到postgres
用户sudo su - postgres
才能链接,需要修改配置文件
sudo vi /var/lib/pgsql/10/data/pg_hba.conf
修改为
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
然后可以通过以下命令从客户端链接
psql -h 127.0.0.1 -p 5432 -U postgres -d exampledb
远程连接
- 为用户添加密码
ALTER USER postgres PASSWORD 'password'
// 或创建新用户
CREATE USER dbuser WITH PASSWORD 'password';
GRANT ALL PRIVILEGES ON DATABASE exampledb TO dbuser;
- 修改配置
/var/lib/pgsql/10/data/pg_hba.conf
为密码登录
# 本地登录无需密码
host all all 127.0.0.1/32 trust
# 远程登录需要密码
host all all 0.0.0.0/0 password
- 修改配置文件
/var/lib/pgsql/10/data/postgresql.conf
,运行远程连接
listen_addresses = '*'
- 重启服务
sudo systemctl restart postgresql-10
Docker
导出配置文件
docker run -i --rm postgres cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf
修改配置文件 postgres.conf
,添加网络、时区、SSL 等配置
listen_addresses = '*'
port = 5432
timezone = 'Asia/Shanghai'
ssl = on
ssl_ca_file = '/etc/ssl/postgres/ca.pem'
ssl_cert_file = '/etc/ssl/postgres/cert.pem'
ssl_key_file = '/etc/ssl/postgres/cert.pem'
配置权限文件 ``pg_hba.conf`
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
# SSL
hostssl all all 0.0.0.0/0 md5
#host all all 0.0.0.0/0 md5
启动
docker run -d --name postgres --restart unless-stopped \
-p 5432:5432 \
-v /data/postgres:/var/lib/postgresql/data \
-v $(pwd)/postgres.conf:/etc/postgres/postgres.conf \
-v $(pwd)/pg_hba.conf:/etc/postgres/pg_hba.conf \
-v /home/your_username/.ssl:/etc/ssl/postgres \
-e POSTGRES_USER='your_username' \
-e POSTGRES_PASSWORD='your_password' \
postgres \
-c 'config_file=/etc/postgres/postgres.conf' \
-c 'hba_file=/etc/postgres/pg_hba.conf'
测试本地链接
docker exec -it postgres psql "host=localhost port=5432 user=your_username dbname=postgres"
测试远程连接
docker run -it --rm \
-v /home/yzchen/.ssl:/etc/ssl/postgres \
postgres psql "host=your_hostname port=5432 user=your_username dbname=postgres sslmode=verify-full sslrootcert=/etc/ssl/postgres/ca.pem sslcert=/etc/ssl/postgres/cert.pem sslkey=/etc/ssl/postgres/cert.pem"
参考
- Dockerhub - postgres
- File Locations
- Setting Parameters
- The
pg_hba.conf
File - Configuring Your PostgreSQL Server for Mutual TLS
- A Complete Guide to Securely Connecting PostgreSQL and Psql Using Mutual TLS
控制台命令
\h
:查看SQL命令的解释,比如\h select
\?
:查看psql命令列表\l
:列出所有数据库\c [database_name]
:连接其他数据库\d
:列出当前数据库的所有表格\d [table_name]
:列出某一张表格的结构\du
:列出所有用户\e
:打开文本编辑器\conninfo
:列出当前数据库和连接\x on
:按列显示
Dump and Restore
# dump
pg_dump -h 127.0.0.1 -p 5432 -U your_user_name database_name > database_name_YYYYMMDD.sql
# dump table data as insert SQL
pg_dump -h 127.0.0.1 -p 5432 -U your_user_name database_name --table=source_table --data-only --column-inserts > tmp.sql
# restore
psql template1 -c 'drop database database_name;' # 先删掉原数据库
psql template1 -c 'create database database_name with owner your_user_name;'
psql database_name -h 127.0.0.1 -p 5432 -U your_user_name < database_name_YYYYMMDD.sql
“template1” 和 “template0” 是 pgsql 的模板数据库。创建新database时,PostgreSQL会基于模板数据库制作一份副本,其中会包含所有的数据库设置和数据文件。
导出 CSV
COPY (SELECT column1, column2, ... FROM table_name WHERE condition) TO '/path/to/output/file.csv' DELIMITER ',' CSV HEADER;
导出JSON
\t
\a
\o file.json
SELECT row_to_json(r) FROM my_table AS r;
SQL
# create database
CREATE DATABASE test;
# create table
CREATE TABLE student (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
# insert and ignore conflict
INSERT INTO my_table (filed1, filed2) VALUES (123, 'abc')
ON CONFLICT DO NOTHING;
# upsert
INSERT INTO my_table (filed1, filed2) VALUES (123, 'abc')
ON CONFLICT (filed1, filed2) DO UPDATE SET filed3 = 'update';
Time
# timestamp
SELECT NOW();
# timestamp to string
SELECT TO_CHAR(NOW(), 'YYYY-MM-DD HH24:MI:SS');
# string to timestamp
SELECT TO_TIMESTAMP('2022-06-21 20:37:51', 'YYYY-MM-DD HH24:MI:SS');
# timestamp to epoch
SELECT CAST(EXTRACT(EPOCH FROM NOW()) AS INTEGER);
# epoch to timestamp
SELECT TO_TIMESTAMP(1656669813);
Cast
# string to int
SELECT CAST(id AS INT) FROM users;
# string array to int array
SELECT str_arr::int[] FROM users;
String
# string to array
SELECT STRING_TO_ARRAY(name_path, ',') FROM groups;
SELECT STRING_TO_ARRAY(id_path, ',')::int[] FROM groups;
NULL
# check a column is null
SELECT * FROM accounts WHERE itime IS NULL;
Python client
Install
pip3 install records
pip3 install psycopg2-binary
Usage
post_url = f"postgresql://{DB_USER}:{DB_PASS}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
# query
QUERY_SELECT = '''
SELECT name, age FROM my_table;
'''
with records.Database(mysql_url) as db:
db.query(QUERY_SELECT)
# insert
QUERY_INSERT = '''
INSERT INTO my_table (name, age) VALUES (:name, :age);
'''
with records.Database(mysql_url) as db:
db.query(QUERY_INSERT, "Tom", 12)