Python Psycopg2 callproc和sql参数

Python Psycopg2 callproc和sql参数,python,psycopg2,plpgsql,Python,Psycopg2,Plpgsql,我有一些SQL函数 CREATE OR REPLACE FUNCTION tools.update_company(IN company_id integer, OUT value integer) RETURNS integer AS $BODY$ BEGIN select * into value from function_making_int(company_id) END;$BODY$ 从Psycopg2(如果这很重要的话,它在Django内部)我知道 但函数返回的输

我有一些SQL函数

CREATE OR REPLACE FUNCTION tools.update_company(IN company_id integer, OUT value integer)
     RETURNS integer AS
 $BODY$

BEGIN 
select * into value from function_making_int(company_id)
END;$BODY$
从Psycopg2(如果这很重要的话,它在Django内部)我知道


但函数返回的输入序列和我给出的完全相同,忽略结果和OUT参数。更改为IN-OUT并传递一些foo值不会改变任何内容。当在数据库中调用SQL函数时,该函数按预期工作

我做了很少的研究,并且检查了psycopg2代码-该函数的当前实现就是这样

select * from function_name(params)
return params

因此,它不会以任何方式修改任何内容。

摘自pyscopg2源代码,使用C-api的callproc的C实现给出以下代码:

/* callproc method - execute a stored procedure */

#define psyco_curs_callproc_doc \
"callproc(procname, parameters=None) -- Execute stored procedure."

static PyObject *
psyco_curs_callproc(cursorObject *self, PyObject *args)
{
    const char *procname = NULL;
    char *sql = NULL;
    Py_ssize_t procname_len, i, nparameters = 0, sl = 0;
    PyObject *parameters = Py_None;
    PyObject *operation = NULL;
    PyObject *res = NULL;

    if (!PyArg_ParseTuple(args, "s#|O",
          &procname, &procname_len, &parameters
       ))
    { goto exit; }

    EXC_IF_CURS_CLOSED(self);
    EXC_IF_ASYNC_IN_PROGRESS(self, callproc);
    EXC_IF_TPC_PREPARED(self->conn, callproc);

    if (self->name != NULL) {
        psyco_set_error(ProgrammingError, self,
                         "can't call .callproc() on named cursors");
        goto exit;
    }

    if (parameters != Py_None) {
        if (-1 == (nparameters = PyObject_Length(parameters))) { goto exit;     }
    }

    /* allocate some memory, build the SQL and create a PyString from it */
    sl = procname_len + 17 + nparameters*3 - (nparameters ? 1 : 0);
    sql = (char*)PyMem_Malloc(sl);
    if (sql == NULL) {
        PyErr_NoMemory();
        goto exit;
    }

    sprintf(sql, "SELECT * FROM %s(", procname);
    for(i=0; i<nparameters; i++) {
         strcat(sql, "%s,");
    }
    sql[sl-2] = ')';
    sql[sl-1] = '\0';

    if (!(operation = Bytes_FromString(sql))) { goto exit; }

    if (0 <= _psyco_curs_execute(self, operation, parameters,
            self->conn->async, 0)) {
        Py_INCREF(parameters);
        res = parameters;
    }

exit:
    Py_XDECREF(operation);
    PyMem_Free((void*)sql);
    return res;
}
是的,实际上代码会在地面上生成一个“选择”SQL来执行操作

/* callproc method - execute a stored procedure */

#define psyco_curs_callproc_doc \
"callproc(procname, parameters=None) -- Execute stored procedure."

static PyObject *
psyco_curs_callproc(cursorObject *self, PyObject *args)
{
    const char *procname = NULL;
    char *sql = NULL;
    Py_ssize_t procname_len, i, nparameters = 0, sl = 0;
    PyObject *parameters = Py_None;
    PyObject *operation = NULL;
    PyObject *res = NULL;

    if (!PyArg_ParseTuple(args, "s#|O",
          &procname, &procname_len, &parameters
       ))
    { goto exit; }

    EXC_IF_CURS_CLOSED(self);
    EXC_IF_ASYNC_IN_PROGRESS(self, callproc);
    EXC_IF_TPC_PREPARED(self->conn, callproc);

    if (self->name != NULL) {
        psyco_set_error(ProgrammingError, self,
                         "can't call .callproc() on named cursors");
        goto exit;
    }

    if (parameters != Py_None) {
        if (-1 == (nparameters = PyObject_Length(parameters))) { goto exit;     }
    }

    /* allocate some memory, build the SQL and create a PyString from it */
    sl = procname_len + 17 + nparameters*3 - (nparameters ? 1 : 0);
    sql = (char*)PyMem_Malloc(sl);
    if (sql == NULL) {
        PyErr_NoMemory();
        goto exit;
    }

    sprintf(sql, "SELECT * FROM %s(", procname);
    for(i=0; i<nparameters; i++) {
         strcat(sql, "%s,");
    }
    sql[sl-2] = ')';
    sql[sl-1] = '\0';

    if (!(operation = Bytes_FromString(sql))) { goto exit; }

    if (0 <= _psyco_curs_execute(self, operation, parameters,
            self->conn->async, 0)) {
        Py_INCREF(parameters);
        res = parameters;
    }

exit:
    Py_XDECREF(operation);
    PyMem_Free((void*)sql);
    return res;
}
c = connection.cursor()
res = c.callproc('tools.update_company', [1, ])