행당 ~ 1800 개의 레코드가있는 고정 폭 원본 파일이 있습니다.COPY FROM stdin을 사용하여 테이블을로드하고 입력 파일을 한 번만 읽음
이 파일을 Postgres 8.3.9의 인스턴스에서 5 개의 다른 테이블에로드해야합니다.
내 딜레마는 파일이 너무 크기 때문에 한 번만 읽어야한다는 것입니다.
이것은 일반적으로 INSERT 또는 COPY를 사용하여 충분히 간단하지만 TRUNCATE를 포함하는 트랜잭션에 COPY FROM 문을 포함하여로드 속도 향상을 얻으려고합니다. 로깅을 피하는 것이 좋습니다. 상당한 부하 속도 증가 (http://www.cirrusql.com/node/3에 따라). 내가 이해하는 한, Postgres 9.x에서 로깅을 비활성화 할 수 있지만 8.3.9에서는 옵션이 없습니다.
아래 스크립트는 필자가 입력 파일을 두 번 읽는 것을 말합니다. 필자는 입력 파일을 한 번만 읽음으로써이를 수행 할 수있는 방법을 피하고 싶습니다. 배시 일 필요는 없습니다. 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
고마워요!
나는 Python에서 파싱을 사용하고 STDIN을 통해 PostgreSQL로 스트리밍을 사용하여 비슷한 것을 구현했습니다. 나는 PSYCOPG2를 사용하지 않고 추한 방법으로 해냈습니다. 내 문제는 내가 당신의 코드를 이해하지 못한다는 것이다. 이 코드는 어떻게 5 가지 테이블에 무언가를로드 할 수 있습니까? 파이썬 프로그램에서 무슨 일이 일어나고 있는지. – David
안녕하세요 @ David - 미안하지만 분명히해야합니다. 위의 코드는 5 대신 2 개의 표만 사용하는 단순화 된 예제입니다. @ 존 바움의 유용한 팁을 토대로 위의 방식을 버렸습니다. 아래를 참조하십시오. 위에서 말한 내용에 관해서는 위의 코드에 몇 가지 주석을 추가하여 조금 더 명확하게 설명 할 것입니다. 위의 Python 스크립트는 표준 입력 스트림에서 고정 폭 입력을 읽고 탭으로 구분 된 값의 문자열로 분리 한 다음 파이프를 사용하여 psql로 리디렉션되는 표준 출력 스트림으로 전송합니다. ". – Stew