使用 callproc 调用存储过程并没有真正在 postgresql 中实现?

call store procedure using callproc do not really implement in postgresql?

我有 python 3.7 和 postgresql:

import psycopg2
...
@app.route('/add', methods=['POST'])
def add():
    cur = get_db().cursor()
    if request.is_json:
        jdata = request.get_json()
        cur.callproc("add", (jdata['tools'], jdata['ip_begin'], jdata['ip_end']))
        result = cur.fetchall()
        print(result)
        cur.close()
        return jsonify({'result': 'add successful'})
    else:
        cur.close()
        return jsonify({'error':"invalid input json data"})

我的商店功能是:

CREATE FUNCTION "public"."add"("tool_name" varchar, "ip_bgn" inet, "ip_end" inet) RETURNS "pg_catalog"."int8"
$$  
DECLARE
mid INTEGER := 0;
ins BIGINT := 0;
BEGIN
  if ip_bgn < ip_end then
INSERT into ip_addresses(tool_name, ip_start, ip_end) VALUES (tool_name, ip_bgn, ip_end) RETURNING id into mid;
    Loop
        if ip_bgn + ins >= ip_end then
            exit;
        end if;
        INSERT into ip_pools(tool_name, ip_address, to_main, status) VALUES(tool_name, ip_bgn+ins, mid, 'free');
        ins := ins + 1;
    end Loop;
end if;
RETURN ins;
END $$

我的输出是:

 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 [(11,)]                   ######################## I have return values
 127.0.0.1 - - [28/Dec/2020 00:37:40] "POST /add HTTP/1.1" 200 -

但是当我访问数据库时,我发现在我的 python 代码执行后数据库没有添加任何行。

数据库和我之前执行的一样

我可以使用 plpgsql 控制台通过相同的存储功能创建真实数据。但是,如果我通过 python 编码 运行,它不会真正添加行和更改表,但 return 数据是可以的。

您不会在任何地方提交对数据库所做的更改。假设你的连接是这样定义的(好像是get_db,你以后可以改):

conn = psycopg2.connect(host="db.host.com", user="username", password="secret")

您需要在关闭游标后提交更改:

cur.callproc("add", (jdata['tools'], jdata['ip_begin'], jdata['ip_end']))
# some code
cur.close()
conn.commit()
# close the connection as well once done
conn.close()

来自pycopg2 documentation

Note that closing a connection without committing the changes first will cause any pending change to be discarded as if a ROLLBACK was performed (unless a different isolation level has been selected: see set_isolation_level()).