私はstdinから行を読み込み、plpythonuストアドプロシージャを使用してこれらの行のデータをPostgreSQLデータベースに挿入しようとしています。このplpythonuストアドプロシージャをデータベースに挿入するにはどうすればよいですか?
私がPython 3の下でプロシージャを呼び出すと、それは実行されます(読み取られた各行のシリアル値を消費します)。 が、データをdbに格納しません。 私はpsqlから同じプロシージャを呼び出すと、db内に1行を挿入して正常に動作します。
アクション:例:については
日day_id 1.
アクションで挿入:無:コマンドライン
結果でファイル名を指定して実行python3 src/load/load_mcv.py < input.txt
ユーザーjazcap53
結果はpsql内からSELECT sl_insert_day('2017-01-02', '05:15');
を実行します2つの連続したday_idが消費されます。
処置:ユーザーとしてのpsql内からjazcap53
の検索結果をSELECT sl_insert_day('2017-01-03', '06:15');
を実行します:1日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)データベースを作成する:
ユーザのPostgresとしてpsqlで、データベースsl_test_mcvをCREATE
。
ステップ2)データベースのinit:
ファイル:DB/database_mcv.ini
[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()