mirror of
https://github.com/psycopg/psycopg2.git
synced 2024-11-25 18:33:44 +03:00
Added new_array_type() function
Allows the creation of a generic array typecaster from Python.
This commit is contained in:
parent
6c8051907c
commit
e3054ac9f3
2
NEWS
2
NEWS
|
@ -1,6 +1,8 @@
|
||||||
What's new in psycopg 2.4.3
|
What's new in psycopg 2.4.3
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
- Added 'new_array_type()' function for easy creation of array
|
||||||
|
typecasters.
|
||||||
- Fixed segfault in case of transaction started with connection lost
|
- Fixed segfault in case of transaction started with connection lost
|
||||||
(and possibly other events).
|
(and possibly other events).
|
||||||
- Rollback connections in transaction or in error before putting them
|
- Rollback connections in transaction or in error before putting them
|
||||||
|
|
|
@ -216,6 +216,9 @@ read:
|
||||||
>>> print type(point), point.x, point.y
|
>>> print type(point), point.x, point.y
|
||||||
<class 'Point'> 10.2 20.3
|
<class 'Point'> 10.2 20.3
|
||||||
|
|
||||||
|
A typecaster created by `!new_type()` can be also used with
|
||||||
|
`~psycopg2.extensions.new_array_type()` to create a typecaster converting a
|
||||||
|
PostgreSQL array into a Python list.
|
||||||
|
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
|
|
|
@ -290,7 +290,7 @@ details.
|
||||||
.. function:: new_type(oids, name, adapter)
|
.. function:: new_type(oids, name, adapter)
|
||||||
|
|
||||||
Create a new type caster to convert from a PostgreSQL type to a Python
|
Create a new type caster to convert from a PostgreSQL type to a Python
|
||||||
object. The created object must be registered using
|
object. The object created must be registered using
|
||||||
`register_type()` to be used.
|
`register_type()` to be used.
|
||||||
|
|
||||||
:param oids: tuple of OIDs of the PostgreSQL type to convert.
|
:param oids: tuple of OIDs of the PostgreSQL type to convert.
|
||||||
|
@ -309,6 +309,23 @@ details.
|
||||||
See :ref:`type-casting-from-sql-to-python` for an usage example.
|
See :ref:`type-casting-from-sql-to-python` for an usage example.
|
||||||
|
|
||||||
|
|
||||||
|
.. function:: new_array_type(oids, name, base_caster)
|
||||||
|
|
||||||
|
Create a new type caster to convert from a PostgreSQL array type to a list
|
||||||
|
of Python object. The object created must be registered using
|
||||||
|
`register_type()` to be used.
|
||||||
|
|
||||||
|
:param oids: tuple of OIDs of the PostgreSQL type to convert. It should
|
||||||
|
probably be the oid of the array type (e.g. the ``typarray`` field in
|
||||||
|
the ``pg_type`` table.
|
||||||
|
:param name: the name of the new type adapter.
|
||||||
|
:param base_caster: a Psycopg typecaster, e.g. created using the
|
||||||
|
`new_type()` function. The caster should be able to parse a single
|
||||||
|
item of the desired type.
|
||||||
|
|
||||||
|
.. versionadded:: 2.4.3
|
||||||
|
|
||||||
|
|
||||||
.. function:: register_type(obj [, scope])
|
.. function:: register_type(obj [, scope])
|
||||||
|
|
||||||
Register a type caster created using `new_type()`.
|
Register a type caster created using `new_type()`.
|
||||||
|
|
|
@ -57,7 +57,7 @@ except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid
|
from psycopg2._psycopg import adapt, adapters, encodings, connection, cursor, lobject, Xid
|
||||||
from psycopg2._psycopg import string_types, binary_types, new_type, register_type
|
from psycopg2._psycopg import string_types, binary_types, new_type, new_array_type, register_type
|
||||||
from psycopg2._psycopg import ISQLQuote, Notify
|
from psycopg2._psycopg import ISQLQuote, Notify
|
||||||
|
|
||||||
from psycopg2._psycopg import QueryCanceledError, TransactionRollbackError
|
from psycopg2._psycopg import QueryCanceledError, TransactionRollbackError
|
||||||
|
|
|
@ -257,7 +257,7 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
" * `conn_or_curs`: A connection, cursor or None"
|
" * `conn_or_curs`: A connection, cursor or None"
|
||||||
|
|
||||||
#define typecast_from_python_doc \
|
#define typecast_from_python_doc \
|
||||||
"new_type(oids, name, adapter) -> new type object\n\n" \
|
"new_type(oids, name, castobj) -> new type object\n\n" \
|
||||||
"Create a new binding object. The object can be used with the\n" \
|
"Create a new binding object. The object can be used with the\n" \
|
||||||
"`register_type()` function to bind PostgreSQL objects to python objects.\n\n" \
|
"`register_type()` function to bind PostgreSQL objects to python objects.\n\n" \
|
||||||
":Parameters:\n" \
|
":Parameters:\n" \
|
||||||
|
@ -268,6 +268,15 @@ psyco_connect(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
" the string representation returned by PostgreSQL (`!None` if ``NULL``)\n" \
|
" the string representation returned by PostgreSQL (`!None` if ``NULL``)\n" \
|
||||||
" and ``cur`` is the cursor from which data are read."
|
" and ``cur`` is the cursor from which data are read."
|
||||||
|
|
||||||
|
#define typecast_array_from_python_doc \
|
||||||
|
"new_array_type(oids, name, baseobj) -> new type object\n\n" \
|
||||||
|
"Create a new binding object to parse an array.\n\n" \
|
||||||
|
"The object can be used with `register_type()`.\n\n" \
|
||||||
|
":Parameters:\n" \
|
||||||
|
" * `oids`: Tuple of ``oid`` of the PostgreSQL types to convert.\n" \
|
||||||
|
" * `name`: Name for the new type\n" \
|
||||||
|
" * `baseobj`: Adapter to perform type conversion of a single array item."
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_psyco_register_type_set(PyObject **dict, PyObject *type)
|
_psyco_register_type_set(PyObject **dict, PyObject *type)
|
||||||
{
|
{
|
||||||
|
@ -758,6 +767,8 @@ static PyMethodDef psycopgMethods[] = {
|
||||||
METH_VARARGS, psyco_register_type_doc},
|
METH_VARARGS, psyco_register_type_doc},
|
||||||
{"new_type", (PyCFunction)typecast_from_python,
|
{"new_type", (PyCFunction)typecast_from_python,
|
||||||
METH_VARARGS|METH_KEYWORDS, typecast_from_python_doc},
|
METH_VARARGS|METH_KEYWORDS, typecast_from_python_doc},
|
||||||
|
{"new_array_type", (PyCFunction)typecast_array_from_python,
|
||||||
|
METH_VARARGS|METH_KEYWORDS, typecast_array_from_python_doc},
|
||||||
|
|
||||||
{"AsIs", (PyCFunction)psyco_AsIs,
|
{"AsIs", (PyCFunction)psyco_AsIs,
|
||||||
METH_VARARGS, psyco_AsIs_doc},
|
METH_VARARGS, psyco_AsIs_doc},
|
||||||
|
|
|
@ -603,6 +603,29 @@ typecast_from_python(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
return typecast_new(name, v, cast, base);
|
return typecast_new(name, v, cast, base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
typecast_array_from_python(PyObject *self, PyObject *args, PyObject *keywds)
|
||||||
|
{
|
||||||
|
PyObject *values, *name = NULL, *base = NULL;
|
||||||
|
typecastObject *obj = NULL;
|
||||||
|
|
||||||
|
static char *kwlist[] = {"values", "name", "baseobj", NULL};
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!O!", kwlist,
|
||||||
|
&PyTuple_Type, &values,
|
||||||
|
&Text_Type, &name,
|
||||||
|
&typecastType, &base)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((obj = (typecastObject *)typecast_new(name, values, NULL, base))) {
|
||||||
|
obj->ccast = typecast_GENERIC_ARRAY_cast;
|
||||||
|
obj->pcast = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (PyObject *)obj;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
typecast_from_c(typecastObject_initlist *type, PyObject *dict)
|
typecast_from_c(typecastObject_initlist *type, PyObject *dict)
|
||||||
{
|
{
|
||||||
|
|
|
@ -77,9 +77,11 @@ HIDDEN int typecast_add(PyObject *obj, PyObject *dict, int binary);
|
||||||
/* the C callable typecastObject creator function */
|
/* the C callable typecastObject creator function */
|
||||||
HIDDEN PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d);
|
HIDDEN PyObject *typecast_from_c(typecastObject_initlist *type, PyObject *d);
|
||||||
|
|
||||||
/* the python callable typecast creator function */
|
/* the python callable typecast creator functions */
|
||||||
HIDDEN PyObject *typecast_from_python(
|
HIDDEN PyObject *typecast_from_python(
|
||||||
PyObject *self, PyObject *args, PyObject *keywds);
|
PyObject *self, PyObject *args, PyObject *keywds);
|
||||||
|
HIDDEN PyObject *typecast_array_from_python(
|
||||||
|
PyObject *self, PyObject *args, PyObject *keywds);
|
||||||
|
|
||||||
/* the function used to dispatch typecasting calls */
|
/* the function used to dispatch typecasting calls */
|
||||||
HIDDEN PyObject *typecast_cast(
|
HIDDEN PyObject *typecast_cast(
|
||||||
|
|
|
@ -285,6 +285,19 @@ class TypesBasicTests(unittest.TestCase):
|
||||||
l1 = self.execute("select -%s;", (-1L,))
|
l1 = self.execute("select -%s;", (-1L,))
|
||||||
self.assertEqual(1, l1)
|
self.assertEqual(1, l1)
|
||||||
|
|
||||||
|
def testGenericArray(self):
|
||||||
|
def caster(s, cur):
|
||||||
|
if s is None: return "nada"
|
||||||
|
return int(s) * 2
|
||||||
|
base = psycopg2.extensions.new_type((23,), "INT4", caster)
|
||||||
|
array = psycopg2.extensions.new_array_type((1007,), "INT4ARRAY", base)
|
||||||
|
|
||||||
|
psycopg2.extensions.register_type(array, self.conn)
|
||||||
|
a = self.execute("select '{1,2,3}'::int4[]")
|
||||||
|
self.assertEqual(a, [2,4,6])
|
||||||
|
a = self.execute("select '{1,2,NULL}'::int4[]")
|
||||||
|
self.assertEqual(a, [2,4,'nada'])
|
||||||
|
|
||||||
|
|
||||||
class AdaptSubclassTest(unittest.TestCase):
|
class AdaptSubclassTest(unittest.TestCase):
|
||||||
def test_adapt_subtype(self):
|
def test_adapt_subtype(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user