【问题标题】:Call Postgres SQL stored procedure From Django从 Django 调用 Postgres SQL 存储过程
【发布时间】:2015-01-07 12:05:16
【问题描述】:

我正在开发一个带有 Postgres SQL 数据库的 Django 项目。我写了一个在 Postgres 上完美运行的存储过程。

现在我想从 Django 1.5 中调用该存储过程。我已经编写了代码,但它会提示错误。

CREATE FUNCTION fn_save_message3(IN msg_sub character varying, IN msg_cont text, IN msg_type character varying, IN msg_category character varying, IN msg_created_by character varying, IN msg_updated_by character varying) RETURNS integer AS
$BODY$ DECLARE msg_id integer := 0;
BEGIN
    INSERT INTO tbl_messages
        (message_subject, message_content, message_type, message_category, 
       created_on, created_by, updated_on, updated_by)
    VALUES 
      (msg_sub, msg_cont, msg_type, msg_category, LOCALTIMESTAMP, 
       msg_created_by, LOCALTIMESTAMP, msg_updated_by);
      Select into msg_id currval('tbl_messages_message_id_seq');
  return msg_id;
END;$BODY$
LANGUAGE plpgsql VOLATILE NOT LEAKPROOF
COST 100;
ALTER FUNCTION public.fn_save_message(IN character varying, IN text, IN character varying, IN character varying, IN character varying, IN character varying)
  OWNER TO gljsxdlvpgfvui;

存储过程没问题,它会返回结果。

c = connection.cursor()
    try:
        c.execute("BEGIN")
        c.callproc("fn_save_message", [Message_Subject, Message_Content, Message_Type, Message_Category, Created_By, updated_by])
        results = c.fetchone()
        c.execute("COMMIT")
    finally:
        c.close()
    print results

在您提出所有建议之后,我的程序终于可以正常工作了。但还剩下一个小问题。

因为我使用results = c.fetchone() 来获取输出参数。 它返回 (13,)

但我只想得到 13 作为字符串或整数,我怎样才能只得到值。

更新:

问题解决了

for item in results:
        message_id = item

【问题讨论】:

标签: python django postgresql stored-procedures


【解决方案1】:
c = connection.cursor()
try:
    c.execute("BEGIN")
    c.callproc("fn_save_message3", (Message_Subject, Message_Content, Message_Type, Message_Category, Created_By, Updated_By))
    results = c.fetchall()
    c.execute("COMMIT")
finally:
    c.close()
print results

您忘记了右括号,并试图在 cursor 而不是 c 上调用函数,并且还遇到了缩进问题。您还应该使用callproc() 记录的here. 函数

正如 catavaran 所说,您应该阅读有关执行自定义 SQL 并使用占位符的文档。此外,在 Django 1.6+ 中,事务是自动提交的,因此不需要c.execute("COMMIT")

【讨论】:

  • 正如你所说,我已经更新了我的代码,现在出现了不同的错误,请参阅我已经更新的问题。它应该接受输入参数,因为我没有在哪里定义它最多接受 2 个参数。
  • @MuhammadTaqiHassanBukhari 更新了答案。新错误意味着 callproc() 方法需要 2 个参数而不是 7 个。initd.org/psycopg/docs/cursor.html#cursor.callproc
【解决方案2】:
    c = connection.cursor()
    try:
        c.execute("BEGIN")
        c.callproc("fn_save_message3", [Message_Subject, Message_Content, Message_Type, Message_Category, Created_By, updated_by])
        results = c.fetchone()
        c.execute("COMMIT")
    finally:
        c.close()
    for item in results:
        message_id = item

【讨论】:

    【解决方案3】:

    c.execute("SELECT fn_save_message3(... 行缺少右括号。在最后一个引号后添加)

    但无论如何,从 python 代码执行 SQL 是一种错误的方法。您应该使用占位符来防止 sql 注入攻击。 Read the documentation 在 django 中正确使用 SQL 的示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-26
      • 2012-02-10
      • 2019-05-11
      • 2014-03-30
      • 2015-05-08
      • 2021-05-26
      相关资源
      最近更新 更多