mirror of
https://github.com/psycopg/psycopg2.git
synced 2025-03-03 07:45:45 +03:00
Merge branch 'types-arrays' into devel
This commit is contained in:
commit
b2c61eaa18
1
NEWS
1
NEWS
|
@ -11,6 +11,7 @@ What's new in psycopg 2.4.5
|
|||
to Menno Smits (tickets #94, #95).
|
||||
- Fixed 'rownumber' during iteration on cursor subclasses.
|
||||
Regression introduced in 2.4.4 (ticket #100).
|
||||
- Added support for 'inet' arrays.
|
||||
|
||||
|
||||
What's new in psycopg 2.4.4
|
||||
|
|
|
@ -325,6 +325,20 @@ details.
|
|||
|
||||
.. versionadded:: 2.4.3
|
||||
|
||||
.. _cast-array-unknown:
|
||||
|
||||
.. note::
|
||||
|
||||
The function can be used to create a generic array typecaster,
|
||||
returning a list of strings: just use the `~psycopg2.STRING` as base
|
||||
typecaster. For instance, if you want to receive from the database an
|
||||
array of :sql:`macaddr`, each address represented by string, you can
|
||||
use::
|
||||
|
||||
psycopg2.extensions.register_type(
|
||||
psycopg2.extensions.new_array_type(
|
||||
(1040,), 'MACADDR[]', psycopg2.STRING))
|
||||
|
||||
|
||||
.. function:: register_type(obj [, scope])
|
||||
|
||||
|
|
|
@ -250,6 +250,7 @@ UUID data type
|
|||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 2.0.9
|
||||
.. versionchanged:: 2.4.5 added inet array support.
|
||||
|
||||
.. doctest::
|
||||
|
||||
|
@ -264,7 +265,7 @@ UUID data type
|
|||
'192.168.0.1/24'
|
||||
|
||||
|
||||
.. autofunction:: register_inet()
|
||||
.. autofunction:: register_inet
|
||||
|
||||
.. autoclass:: Inet
|
||||
|
||||
|
|
|
@ -109,6 +109,13 @@ Transferring binary data from PostgreSQL 9.0 doesn't work.
|
|||
.. __: http://www.postgresql.org/docs/9.0/static/datatype-binary.html
|
||||
.. __: http://www.postgresql.org/docs/9.0/static/runtime-config-client.html#GUC-BYTEA-OUTPUT
|
||||
|
||||
Arrays of *TYPE* are not casted to list.
|
||||
Arrays are only casted to list when their oid is known, and an array
|
||||
typecaster is registered for them. If there is no typecaster, the array is
|
||||
returned unparsed from PostgreSQL (e.g. ``{a,b,c}``). It is easy to create
|
||||
a generic arrays typecaster, returning a list of array: an example is
|
||||
provided in the `~psycopg2.extensions.new_array_type()` documentation.
|
||||
|
||||
|
||||
Best practices
|
||||
--------------
|
||||
|
|
|
@ -294,7 +294,7 @@ the SQL string that would be sent to the database.
|
|||
`bytea_output`__ configuration parameter to ``escape``, either in the
|
||||
server configuration file or in the client session (using a query such as
|
||||
``SET bytea_output TO escape;``) before receiving binary data.
|
||||
|
||||
|
||||
.. __: http://www.postgresql.org/docs/9.0/static/datatype-binary.html
|
||||
.. __: http://www.postgresql.org/docs/9.0/static/runtime-config-client.html#GUC-BYTEA-OUTPUT
|
||||
|
||||
|
@ -334,6 +334,14 @@ the SQL string that would be sent to the database.
|
|||
>>> cur.mogrify("SELECT %s;", ([10, 20, 30], ))
|
||||
'SELECT ARRAY[10, 20, 30];'
|
||||
|
||||
.. note::
|
||||
|
||||
Reading back from PostgreSQL, arrays are converted to list of Python
|
||||
objects as expected, but only if the types are known one. Arrays of
|
||||
unknown types are returned as represented by the database (e.g.
|
||||
``{a,b,c}``). You can easily create a typecaster for :ref:`array of
|
||||
unknown types <cast-array-unknown>`.
|
||||
|
||||
.. _adapt-tuple:
|
||||
|
||||
.. index::
|
||||
|
|
|
@ -455,14 +455,21 @@ class UUID_adapter(object):
|
|||
__str__ = getquoted
|
||||
|
||||
def register_uuid(oids=None, conn_or_curs=None):
|
||||
"""Create the UUID type and an uuid.UUID adapter."""
|
||||
"""Create the UUID type and an uuid.UUID adapter.
|
||||
|
||||
:param oids: oid for the PostgreSQL :sql:`uuid` type, or 2-items sequence
|
||||
with oids of the type and the array. If not specified, use PostgreSQL
|
||||
standard oids.
|
||||
:param conn_or_curs: where to register the typecaster. If not specified,
|
||||
register it globally.
|
||||
"""
|
||||
|
||||
import uuid
|
||||
|
||||
if not oids:
|
||||
oid1 = 2950
|
||||
oid2 = 2951
|
||||
elif type(oids) == list:
|
||||
elif isinstance(oids, (list, tuple)):
|
||||
oid1, oid2 = oids
|
||||
else:
|
||||
oid1 = oids
|
||||
|
@ -491,13 +498,13 @@ class Inet(object):
|
|||
"""
|
||||
def __init__(self, addr):
|
||||
self.addr = addr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return "%s(%r)" % (self.__class__.__name__, self.addr)
|
||||
|
||||
def prepare(self, conn):
|
||||
self._conn = conn
|
||||
|
||||
|
||||
def getquoted(self):
|
||||
obj = _A(self.addr)
|
||||
if hasattr(obj, 'prepare'):
|
||||
|
@ -510,13 +517,32 @@ class Inet(object):
|
|||
|
||||
def __str__(self):
|
||||
return str(self.addr)
|
||||
|
||||
|
||||
def register_inet(oid=None, conn_or_curs=None):
|
||||
"""Create the INET type and an Inet adapter."""
|
||||
if not oid: oid = 869
|
||||
_ext.INET = _ext.new_type((oid, ), "INET",
|
||||
"""Create the INET type and an Inet adapter.
|
||||
|
||||
:param oid: oid for the PostgreSQL :sql:`inet` type, or 2-items sequence
|
||||
with oids of the type and the array. If not specified, use PostgreSQL
|
||||
standard oids.
|
||||
:param conn_or_curs: where to register the typecaster. If not specified,
|
||||
register it globally.
|
||||
"""
|
||||
if not oid:
|
||||
oid1 = 869
|
||||
oid2 = 1041
|
||||
elif isinstance(oid, (list, tuple)):
|
||||
oid1, oid2 = oid
|
||||
else:
|
||||
oid1 = oid
|
||||
oid2 = 1041
|
||||
|
||||
_ext.INET = _ext.new_type((oid1, ), "INET",
|
||||
lambda data, cursor: data and Inet(data) or None)
|
||||
_ext.INETARRAY = _ext.new_array_type((oid2, ), "INETARRAY", _ext.INET)
|
||||
|
||||
_ext.register_type(_ext.INET, conn_or_curs)
|
||||
_ext.register_type(_ext.INETARRAY, conn_or_curs)
|
||||
|
||||
return _ext.INET
|
||||
|
||||
|
||||
|
|
|
@ -82,13 +82,22 @@ class TypesExtrasTests(unittest.TestCase):
|
|||
|
||||
def testINET(self):
|
||||
psycopg2.extras.register_inet()
|
||||
i = "192.168.1.0/24";
|
||||
i = psycopg2.extras.Inet("192.168.1.0/24")
|
||||
s = self.execute("SELECT %s AS foo", (i,))
|
||||
self.failUnless(i == s)
|
||||
self.failUnless(i.addr == s.addr)
|
||||
# must survive NULL cast to inet
|
||||
s = self.execute("SELECT NULL::inet AS foo")
|
||||
self.failUnless(s is None)
|
||||
|
||||
def testINETARRAY(self):
|
||||
psycopg2.extras.register_inet()
|
||||
i = psycopg2.extras.Inet("192.168.1.0/24")
|
||||
s = self.execute("SELECT %s AS foo", ([i],))
|
||||
self.failUnless(i.addr == s[0].addr)
|
||||
# must survive NULL cast to inet
|
||||
s = self.execute("SELECT NULL::inet[] AS foo")
|
||||
self.failUnless(s is None)
|
||||
|
||||
def test_inet_conform(self):
|
||||
from psycopg2.extras import Inet
|
||||
i = Inet("192.168.1.0/24")
|
||||
|
|
Loading…
Reference in New Issue
Block a user