如何将此plpythonu存储过程插入数据库?

时间:2017-04-11 22:18:46

标签: python postgresql stored-procedures fedora-25 plpython

我尝试从stdin读取行,并使用plpythonu存储过程将这些行中的数据插入到PostgreSQL数据库中。

当我在Python 3下调用该过程时,它会运行(为每行读取消耗一个串行值), 但是不会在数据库中存储任何数据。 当我从psql调用相同的过程时,它工作正常,在数据库中插入一行。

例如

操作:从psql中以用户jazcap53为运行SELECT sl_insert_day('2017-01-02', '05:15'); 结果:插入day_id 1的日期。

操作:在命令行运行python3 src/load/load_mcv.py < input.txt
结果:未插入任何内容,但会消耗2个连续的day_id。

操作:从psql中以用户jazcap53为运行SELECT sl_insert_day('2017-01-03', '06:15'); 结果:插入day_id 4日。

file: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中作为用户postgres,
    创建数据库sl_test_mcv;

步骤2)数据库初始化:

file:db / database_mcv.ini

[postgresql]
host=localhost
database=sl_test_mcv
user=jazcap53
password=*****

步骤3)运行数据库配置:

file: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)创建表格:

file: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)创建程序:

file: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)授予权限:

file: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 / load_mcv.py&lt; input.txt中:

file:src / load / 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 个答案:

答案 0 :(得分:1)

conn.commit()

之后cur.close()