公司最近有个项目数据库里表需要使用到另外一个数据库里表的某两个字段,而且并不是直接查询就能插入到新表里
id |
sn |
customer |
1 |
xxxx |
Test |
id |
sn |
customer_id |
1 |
xxxx |
1 |
我开始考虑的是使用python脚本去查数据库,然后逻辑判断,这种方式也是可以实现的。
进行插入但表里的数据有几百万条记录,使用python脚本迁移,有网络的开销,执行的速度会很慢,
所以我考使用postgresql的存储过程进行迁移
思路:在新库创建schema,然后将旧表导入schema里,
然后再存储过程脚本里查询schema里的旧表,在插入新表逻辑时进行查询判断,然后将记录插入到新表里
vim bossToAd.sql
创建迁移脚本bossToAd.sql文件,以下为代码内容
CREATE OR REPLACE FUNCTION bossToadfunc ()
RETURNS integer AS $$
declare
row RECORD;
sn_v varchar;
customer_v varchar;
ids RECORD;
c_id integer := 0;
count integer :=0;
BEGIN
FOR row IN SELECT sn,customer FROM boss_tmp.t_terminal LOOP
count := count + 1;
sn_v := row.sn;
customer_v := row.customer;
EXECUTE 'select id from t_customer where customer_name='||quote_literal(customer_v) into ids;
IF ids IS NULL THEN
EXECUTE 'insert into t_customer (customer_name) VALUES ('||
quote_literal(customer_v)||') RETURNING id' INTO ids;
c_id = ids.id;
ELSE
c_id = ids.id;
END IF;
EXECUTE 'insert into t_sn (sn_value,customer_id) VALUES ('
||quote_literal(sn_v)||','||
quote_literal(c_id)||') on conflict(sn_value) do update set customer_id='
||quote_literal(c_id);
END LOOP;
return count;
END;
$$ LANGUAGE plpgsql;
select bossToadfunc();
导出boss数据库的t_terminal表
pg_dump -h 192.168.10.201 -p 23451 -U postgres -t t_terminal -d boss > boss.sql
sed -i 's/^SET search_path = public, pg_catalog;$/SET search_path = boss_tmp, pg_catalog;/' boss.sql
创建名为boss_tmp的schema
登录adserver数据库后执行创建schema
su postgres
psql -p 23451 -h 192.168.10.202 -U postgres -d adserver
create schema boss_tmp;
\q 退出数据库输入端
导入数据
psql -p 23451 -h 192.168.10.202 -U postgres -d adserver < boss.sql
重新登录adserver
psql -p 23451 -h 192.168.10.202 -U postgres -d adserver
\i bossToAd.sql