stdin에서 줄을 읽으려고하고 plpythonu 저장 프로 시저를 사용하여 그 줄의 데이터를 PostgreSQL db에 삽입하려고합니다.이 plpythonu 저장 프로 시저를 데이터베이스에 삽입하려면 어떻게해야합니까?
파이썬 3에서 프로 시저를 호출하면 이 실행되지만 (각 행 읽기에 대해 일련 값 사용) db에는 데이터가 저장되지 않습니다. psql에서 같은 프로 시저를 호출하면 db에 한 줄만 삽입하면됩니다.
이작업 : : 사용자로 psql의 내부에서 jazcap53
결과를 SELECT sl_insert_day('2017-01-02', '05:15');
을 실행 예를를 들어
명령 줄
결과에 python3 src/load/load_mcv.py < input.txt
을 실행 : 하루 1
액션 day_id 삽입하지 아무것도 삽입되었지만 2 serial_id가 소비되었습니다.
조치 : 사용자로 psql의 내부에서 jazcap53
결과를 SELECT sl_insert_day('2017-01-03', '06:15');
을 실행 일 day_id 4.
파일 삽입 : input.txt를 :
DAY, 2017-01-05, 06:00
DAY, 2017-01-06, 07:00
출력 :
('sl_insert_day() succeeded',)
('sl_insert_day() succeeded',)
저는 Fedora 25, Python 3.6.0 및 PostgreSQL 9.5.6을 실행하고 있습니다.
도와 주실 수있는 분들께 고맙습니다!
다음은이 동작을 재현하는 MCV 예제입니다. 제 8 단계 또는 6 단계에서 문제가 발생할 것으로 예상됩니다. 다른 단계는 완전성을 위해 포함되어 있습니다. MCV를 만드는 데 사용
단계들은
단계 1) 데이터베이스의 생성 :
사용자 포스트 그레스 등 psql의에서는데이터베이스를 만들 sl_test_mcv
;
2 단계) 데이터베이스 초기화 :
파일 :/database_mcv.ini DB
[postgresql]
host=localhost
database=sl_test_mcv
user=jazcap53
password=*****
3 단계) 실행 데이터베이스 설정 :
파일 : DB/config_mcv.py
from configparser import ConfigParser
def config(filename='db/database_mcv.ini', section='postgresql'):
parser = ConfigParser()
parser.read(filename)
db = {}
if parser.has_section(section):
params = parser.items(section)
for param in params:
db[param[0]] = param[1]
else:
raise Exception('Section {} not found in the {} file'.format(section, filename))
return db
4 단계) 테이블 만들기 :
파일 : db/create_tables_mcv.SQL
DROP TABLE IF EXISTS sl_day CASCADE;
CREATE TABLE sl_day (
day_id SERIAL UNIQUE,
start_date date NOT NULL,
start_time time NOT NULL,
PRIMARY KEY (day_id)
);
5 단계) 작성 언어 :
CREATE LANGUAGE plpythonu;
6 단계) 작성 절차 :
파일 : DB/create_procedures_mcv.sql
DROP FUNCTION sl_insert_day(date, time without time zone);
CREATE FUNCTION sl_insert_day(new_start_date date,
new_start_time time without time zone) RETURNS text AS $$
from plpy import spiexceptions
try:
plan = plpy.prepare("INSERT INTO sl_day (start_date, start_time) \
VALUES($1, $2)", ["date", "time without time zone"])
plpy.execute(plan, [new_start_date, new_start_time])
except plpy.SPIError, e:
return "error: SQLSTATE %s" % (e.sqlstate,)
else:
return "sl_insert_day() succeeded"
$$ LANGUAGE plpythonu;
7 단계)을 부여 권한 :
파일 : DB/grant_privileges_mcv.sql
GRANT SELECT, UPDATE, INSERT, DELETE ON sl_day TO jazcap53;
GRANT USAGE ON sl_day_day_id_seq TO jazcap53;
8 단계) python3의 SRC /로드/load_mcv.py으로 실행 절차 < input.txt를 :
파일 : SRC /로드/load_mcv.py
import sys
import psycopg2
from spreadsheet_etl.db.config_mcv import config
def conn_exec():
conn = None
try:
params = config()
conn = psycopg2.connect(**params)
cur = conn.cursor()
last_serial_val = 0
while True:
my_line = sys.stdin.readline()
if not my_line:
break
line_list = my_line.rstrip().split(', ')
if line_list[0] == 'DAY':
cur.execute('SELECT sl_insert_day(\'{}\', \'{}\')'.
format(line_list[1], line_list[2]))
print(cur.fetchone())
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
if __name__ == '__main__':
conn_exec()