2017-04-11 8 views
0

私は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() 

答えて

1

Do conn.commit()cur.close()

関連する問題