将PostgreSQL输出参数返回给Python将返回预先提交的值

将PostgreSQL输出参数返回给Python将返回预先提交的值,python,postgresql,stored-procedures,Python,Postgresql,Stored Procedures,我有一个存储过程,它可以对客户采集的仪表读数执行很多操作,并且应该在最后重新计算客户的实时余额。这一切都很好,但我想稍微调整一下,如果过程是以交互/同步方式运行的,而不是以批处理模式运行的,则将实时平衡返回给调用者。我实际上传回了两个输出参数: 客户是否因为其读数与估计值相差甚远而被重新收费 客户的新实时余额-根据最近的读数估计,几乎总是会发生变化 我的过程是这样调用的:callstaging.process\u reading\u batch('32f6c6cd-d72c-467c-932

我有一个存储过程,它可以对客户采集的仪表读数执行很多操作,并且应该在最后重新计算客户的实时余额。这一切都很好,但我想稍微调整一下,如果过程是以交互/同步方式运行的,而不是以批处理模式运行的,则将实时平衡返回给调用者。我实际上传回了两个输出参数:

  • 客户是否因为其读数与估计值相差甚远而被重新收费
  • 客户的新实时余额-根据最近的读数估计,几乎总是会发生变化
我的过程是这样调用的:
callstaging.process\u reading\u batch('32f6c6cd-d72c-467c-932a-31d553ad6f69':uuid,true),其中第一个参数是唯一的UUID,第二个参数表示我们处于交互模式,希望恢复平衡

我的过程的头块实际上如下所示:

CREATE OR REPLACE PROCEDURE staging.process_reading_batch (
    pb_batch_id uuid,
    pb_interactive boolean DEFAULT false,
    pb_force_validation boolean DEFAULT false,
    pb_reprocess boolean DEFAULT false,
    pb_logging boolean DEFAULT false,
    inout pb_has_cancelled_bills boolean DEFAULT false,
    inout pb_live_balance numeric(9,2) DEFAULT 0)
到目前为止一切都很好,除了我没有办法看到我用来运行这个过程的工具的输出值。如果我使用SQL Server(例如),我会声明几个变量,在执行过程时传入这些变量,然后在完成时检查它们。我不知道PostgreSQL是否能做到这一点,但我假设不能做到

相反,我使用Python脚本调用该过程:

# call the stored procedure to interactively process the batch
cursorBilling.execute("CALL staging.process_reading_batch('32f6c6cd-d72c-467c-932a-31d553ad6f69'::uuid, true);")
connectionBilling.commit()
result = cursorBilling.fetchall()
for row in result:
    print(row[0])
    print(row[1])
这是可行的,但返回的动态平衡不是当前平衡,而是添加新读数之前的平衡。因此,如果客户的活期余额为100.00英镑,我添加了一些读数,他们的余额移动到110.00英镑,那么我将得到返回的活期余额为100.00英镑,即之前的值。第二次运行该过程时,将正确返回live balance,但这只是因为它这次没有更改

我假设发生的情况如下:

  • 我加上读数,这是没有承诺的
  • 我重新计算了实时余额,但这也没有实现
  • 我查询实时余额,并获取提交的(以前的)余额
  • 我将此值作为活动余额返回
  • 我提交更改,然后更新活动余额
  • 我将旧的余额传递回消费者
现在,这是一种过度杀伤力,但在过程中,这是更新活动余额的调用:

-- Recalculate Unbilled
customer_list := ARRAY(SELECT DISTINCT customer_id FROM register_batch_summary_temp);
CALL billing.calculate_unbilled(customer_list, current_date, pb_logging);
-- If this is interactive then we need to set the new balance
IF pb_interactive = true THEN
    -- Get the first customer from the array, as there should only be one customer
    pb_customer_id := customer_list[1];

    SELECT
        COALESCE(ub.unbilled_total, 0)
    INTO
        pb_live_balance
    FROM
        billing.unbilled_header ub
    WHERE
        ub.customer_id = pb_customer_id;
END IF;
…这是紧接着返回实时余额的代码:

-- Recalculate Unbilled
customer_list := ARRAY(SELECT DISTINCT customer_id FROM register_batch_summary_temp);
CALL billing.calculate_unbilled(customer_list, current_date, pb_logging);
-- If this is interactive then we need to set the new balance
IF pb_interactive = true THEN
    -- Get the first customer from the array, as there should only be one customer
    pb_customer_id := customer_list[1];

    SELECT
        COALESCE(ub.unbilled_total, 0)
    INTO
        pb_live_balance
    FROM
        billing.unbilled_header ub
    WHERE
        ub.customer_id = pb_customer_id;
END IF;
我99%确信,如果我可以调用该过程并直接从作为SQL的一部分运行的过程中返回输出参数,那么这将是可行的,而且我看到的问题仅仅是因为Python对事务做了奇怪的事情

最后,如果我从Python脚本中删除
connectionBilling.commit()
,那么我会得到以前的活动余额,而活动余额不会更新,或者添加新的读数,等等