加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

database – 使用COPY FROM stdin加载表,只读取一次输入文件

发布时间:2020-12-15 21:03:17 所属栏目:安全 来源:网络整理
导读:我有一个大的(~60万行)固定宽度源文件,每行约1800条记录. 我需要将此文件加载到Postgres 8.3.9的一个实例上的5个不同的表中. 我的困境是,因为文件太大,我只想阅读一次. 这很简单,使用INSERT或COPY正常,但我试图通过在包含TRUNCATE的事务中包含我的COPY FROM
我有一个大的(~60万行)固定宽度源文件,每行约1800条记录.

我需要将此文件加载到Postgres 8.3.9的一个实例上的5个不同的表中.

我的困境是,因为文件太大,我只想阅读一次.

这很简单,使用INSERT或COPY正常,但我试图通过在包含TRUNCATE的事务中包含我的COPY FROM语句来提高负载速度 – 避免记录,这应该会提供相当大的负载速度提升(根据http://www.cirrusql.com/node/3).据我了解,您可以禁用Postgres 9.x中的日志记录 – 但我在8.3.9上没有该选项.

下面的脚本让我读取输入文件两次,我想避免…有关如何通过只读取一次输入文件来实现这一点的任何想法?不必是bash – 我也尝试过使用psycopg2,但无法弄清楚如何将文件输出流式传输到COPY语句中,如下所示.我无法复制文件,因为我需要动态解析它.

#!/bin/bash

table1="copytest1"
table2="copytest2"

#note: $1 refers to the first argument used when invoking this script
#which should be the location of the file one wishes to have python
#parse and stream out into psql to be copied into the data tables

( echo 'BEGIN;'
  echo 'TRUNCATE TABLE ' ${table1} ';'
  echo 'COPY ' ${table1} ' FROM STDIN'
  echo "WITH NULL AS '';"
  cat $1 | python2.5 ~/parse_${table1}.py 
  echo '.'
  echo 'TRUNCATE TABLE ' ${table2} ';'
  echo 'COPY ' ${table2} ' FROM STDIN'
  echo "WITH NULL AS '';"
  cat $1 | python2.5 ~/parse_${table2}.py 
  echo '.'
  echo 'COMMIT;'
) | psql -U postgres -h chewy.somehost.com -p 5473 -d db_name

exit 0

谢谢!

解决方法

您可以使用 named pipes代替您的匿名管道.
有了这个概念,你的python脚本可以通过不同的psql进程和相应的数据来填充表.

创建管道:

mkfifo fifo_table1
mkfifo fifo_table2

运行psql实例:

psql db_name < fifo_table1 &
psql db_name < fifo_table2 &

你的python脚本会看起来如此(Pseudocode):

SQL_BEGIN = """
BEGIN;
TRUNCATE TABLE %s;
COPY %s FROM STDIN WITH NULL AS '';
"""
fifo1 = open('fifo_table1','w')
fifo2 = open('fifo_table2','w')

bigfile = open('mybigfile','r')

print >> fifo1,SQL_BEGIN % ('table1','table1') #ugly,with python2.6 you could use .format()-Syntax     
print >> fifo2,SQL_BEGIN % ('table2','table2')      

for line in bigfile:
  # your code,which decides where the data belongs to
  # if data belongs to table1
  print >> fifo1,data
  # else
  print >> fifo2,data

print >> fifo1,'COMMIT;'
print >> fifo2,'COMMIT;'

fifo1.close()
fifo2.close()

也许这不是最优雅的解决方案,但它应该有效.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读