fix(extra):object type error, change to only support string or str-able params

This commit is contained in:
vimiix
2023-08-29 11:34:52 +08:00
parent d81dec06b9
commit 372e59e53a
2 changed files with 34 additions and 21 deletions

View File

@ -1142,7 +1142,7 @@ def register_composite(name, conn_or_curs, globally=False, factory=None):
return caster return caster
def _paginate(seq, page_size): def _paginate(seq, page_size, to_byte=False):
"""Consume an iterable and return it in chunks. """Consume an iterable and return it in chunks.
Every chunk is at most `page_size`. Never return an empty chunk. Every chunk is at most `page_size`. Never return an empty chunk.
@ -1152,7 +1152,16 @@ def _paginate(seq, page_size):
while True: while True:
try: try:
for i in range(page_size): for i in range(page_size):
page.append(next(it)) if not to_byte:
page.append(next(it))
continue
vs = next(it)
if isinstance(vs, (list, tuple)):
# Ignore None object
# Serialized params to bytes
page.append(list(map(lambda v: v if v is None else str(v).encode('utf-8'), vs)))
else:
page.append(vs)
yield page yield page
page = [] page = []
except StopIteration: except StopIteration:
@ -1308,16 +1317,17 @@ def execute_prepared_batch(cur, prepared_statement_name, args_list, page_size=10
r""" r"""
[openGauss libpq only] [openGauss libpq only]
Execute prepared statement with api `PQexecPreparedBatch` (new api in openGauss) Execute prepared statement with api `PQexecPreparedBatch` (new api in openGauss's libpq.so)
Param: Arguments:
argslist: 2d list, do nothing if empty argslist: Two-dimensional list, if empty, return directly
Each parameter in the argument list must be a string or be string-able(should implements `__str__` magic method)
""" """
if len(args_list) == 0: if len(args_list) == 0:
return return
nparams = len(args_list[0]) nparams = len(args_list[0])
for page in _paginate(args_list, page_size=page_size): for page in _paginate(args_list, page_size=page_size, to_byte=True):
cur.execute_prepared_batch(prepared_statement_name, nparams, len(page), page) cur.execute_prepared_batch(prepared_statement_name, nparams, len(page), page)
@ -1325,14 +1335,15 @@ def execute_params_batch(cur, sql_format, args_list, page_size=100):
r""" r"""
[openGauss libpq only] [openGauss libpq only]
Execute sql with api `PQexecParamsBatch` (new api in openGauss) Execute sql with api `PQexecParamsBatch` (new api in openGauss's libpq.so)
Arguments: Arguments:
argslist: 2d list, do nothing if empty argslist: Two-dimensional list, if empty, return directly
Each parameter in the argument list must be a string or be string-able(should implements `__str__` magic method)
""" """
if len(args_list) == 0: if len(args_list) == 0:
return return
nparams = len(args_list[0]) nparams = len(args_list[0])
for page in _paginate(args_list, page_size=page_size): for page in _paginate(args_list, page_size=page_size, to_byte=True):
cur.execute_params_batch(sql_format, nparams, len(page), page) cur.execute_params_batch(sql_format, nparams, len(page), page)

View File

@ -628,7 +628,7 @@ curs_execute_prepared_batch(cursorObject *self, PyObject *args)
int nParams = 0, nBatch = 0; int nParams = 0, nBatch = 0;
PyObject *argsList = NULL; PyObject *argsList = NULL;
Py_ssize_t rowIdx, colIdx, total; int rowIdx, colIdx, total;
char **paramValues = NULL; char **paramValues = NULL;
PGresult *res = NULL; PGresult *res = NULL;
@ -642,7 +642,7 @@ curs_execute_prepared_batch(cursorObject *self, PyObject *args)
} }
Dprintf("execute_prepared_batch parsed statement_name: %s, nParams: %d, nBatch: %d", Dprintf("execute_prepared_batch parsed statement_name: %s, nParams: %d, nBatch: %d",
stmtName, nParams, nBatch); stmtName, nParams, nBatch);
total = nBatch*nParams; total = nBatch * nParams;
EXC_IF_CURS_CLOSED(self); EXC_IF_CURS_CLOSED(self);
EXC_IF_CURS_ASYNC(self, execute_prepared_batch); EXC_IF_CURS_ASYNC(self, execute_prepared_batch);
@ -679,11 +679,12 @@ curs_execute_prepared_batch(cursorObject *self, PyObject *args)
PyObject *argItem = PySequence_GetItem(rowArgs, colIdx); PyObject *argItem = PySequence_GetItem(rowArgs, colIdx);
if (argItem == Py_None) { if (argItem == Py_None) {
paramValues[rowIdx*nParams+colIdx] = "NULL"; paramValues[rowIdx * nParams + colIdx] = NULL;
} else { } else {
PyObject *t = microprotocol_getquoted(argItem, self->conn); if (!(argItem = psyco_ensure_bytes(argItem))) {
paramValues[rowIdx*nParams+colIdx] = strdup(Bytes_AsString(t)); goto exit;
Py_XDECREF(t); }
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
} }
Py_XDECREF(argItem); Py_XDECREF(argItem);
} }
@ -715,7 +716,7 @@ curs_execute_params_batch(cursorObject *self, PyObject *args)
int nParams = 0, nBatch = 0; int nParams = 0, nBatch = 0;
PyObject *argsList = NULL; PyObject *argsList = NULL;
Py_ssize_t rowIdx, colIdx, total; int rowIdx, colIdx, total;
char **paramValues = NULL; char **paramValues = NULL;
PGresult *res = NULL; PGresult *res = NULL;
@ -729,7 +730,7 @@ curs_execute_params_batch(cursorObject *self, PyObject *args)
Dprintf("execute_params_batch parsed sql: %s, nParams: %d, nBatch: %d", Dprintf("execute_params_batch parsed sql: %s, nParams: %d, nBatch: %d",
sql, nParams, nBatch); sql, nParams, nBatch);
total = nBatch*nParams; total = nBatch * nParams;
EXC_IF_CURS_CLOSED(self); EXC_IF_CURS_CLOSED(self);
EXC_IF_CURS_ASYNC(self, execute_params_batch); EXC_IF_CURS_ASYNC(self, execute_params_batch);
@ -765,11 +766,12 @@ curs_execute_params_batch(cursorObject *self, PyObject *args)
PyObject *argItem = PySequence_GetItem(rowArgs, colIdx); PyObject *argItem = PySequence_GetItem(rowArgs, colIdx);
if (argItem == Py_None) { if (argItem == Py_None) {
paramValues[rowIdx*nParams+colIdx] = "NULL"; paramValues[rowIdx * nParams + colIdx] = NULL;
} else { } else {
PyObject *t = microprotocol_getquoted(argItem, self->conn); if (!(argItem = psyco_ensure_bytes(argItem))) {
paramValues[rowIdx*nParams+colIdx] = strdup(Bytes_AsString(t)); goto exit;
Py_XDECREF(t); }
paramValues[rowIdx * nParams + colIdx] = Bytes_AsString(argItem);
} }
Py_XDECREF(argItem); Py_XDECREF(argItem);
} }