summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql')
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py69
-rw-r--r--lib/sqlalchemy/dialects/postgresql/pg8000.py22
-rw-r--r--lib/sqlalchemy/dialects/postgresql/psycopg2.py15
3 files changed, 87 insertions, 19 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index 0d103cb0d..7b1a97c32 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -94,13 +94,18 @@ from sqlalchemy.sql import compiler, expression, util as sql_util
from sqlalchemy.sql import operators as sql_operators
from sqlalchemy import types as sqltypes
+try:
+ from uuid import UUID as _python_UUID
+except ImportError:
+ _python_UUID = None
+
from sqlalchemy.types import INTEGER, BIGINT, SMALLINT, VARCHAR, \
CHAR, TEXT, FLOAT, NUMERIC, \
DATE, BOOLEAN
-_DECIMAL_TYPES = (1700, 1231)
+_DECIMAL_TYPES = (1231, 1700)
_FLOAT_TYPES = (700, 701, 1021, 1022)
-
+_INT_TYPES = (20, 21, 23, 26, 1005, 1007, 1016)
class REAL(sqltypes.Float):
__visit_name__ = "REAL"
@@ -134,6 +139,12 @@ class TIME(sqltypes.TIME):
self.precision = precision
class INTERVAL(sqltypes.TypeEngine):
+ """Postgresql INTERVAL type.
+
+ The INTERVAL type may not be supported on all DBAPIs.
+ It is known to work on psycopg2 and not pg8000 or zxjdbc.
+
+ """
__visit_name__ = 'INTERVAL'
def __init__(self, precision=None):
self.precision = precision
@@ -156,17 +167,67 @@ class BIT(sqltypes.TypeEngine):
PGBit = BIT
class UUID(sqltypes.TypeEngine):
+ """Postgresql UUID type.
+
+ Represents the UUID column type, interpreting
+ data either as natively returned by the DBAPI
+ or as Python uuid objects.
+
+ The UUID type may not be supported on all DBAPIs.
+ It is known to work on psycopg2 and not pg8000.
+
+ """
__visit_name__ = 'UUID'
+
+ def __init__(self, as_uuid=False):
+ """Construct a UUID type.
+
+
+ :param as_uuid=False: if True, values will be interpreted
+ as Python uuid objects, converting to/from string via the
+ DBAPI.
+
+ """
+ if as_uuid and _python_UUID is None:
+ raise NotImplementedError(
+ "This version of Python does not support the native UUID type."
+ )
+ self.as_uuid = as_uuid
+
+ def bind_processor(self, dialect):
+ if self.as_uuid:
+ def process(value):
+ if value is not None:
+ value = str(value)
+ return value
+ return process
+ else:
+ return None
+
+ def result_processor(self, dialect, coltype):
+ if self.as_uuid:
+ def process(value):
+ if value is not None:
+ value = _python_UUID(value)
+ return value
+ return process
+ else:
+ return None
+
PGUuid = UUID
class ARRAY(sqltypes.MutableType, sqltypes.Concatenable, sqltypes.TypeEngine):
"""Postgresql ARRAY type.
Represents values as Python lists.
+
+ The ARRAY type may not be supported on all DBAPIs.
+ It is known to work on psycopg2 and not pg8000.
**Note:** be sure to read the notes for
- :class:`~sqlalchemy.types.MutableType` regarding ORM
- performance implications.
+ :class:`.MutableType` regarding ORM
+ performance implications. The :class:`.ARRAY` type's
+ mutability can be disabled using the "mutable" flag.
"""
__visit_name__ = 'ARRAY'
diff --git a/lib/sqlalchemy/dialects/postgresql/pg8000.py b/lib/sqlalchemy/dialects/postgresql/pg8000.py
index 6af2cbd76..7b1d8e6a7 100644
--- a/lib/sqlalchemy/dialects/postgresql/pg8000.py
+++ b/lib/sqlalchemy/dialects/postgresql/pg8000.py
@@ -9,14 +9,16 @@ URLs are of the form
Unicode
-------
-pg8000 requires that the postgresql client encoding be configured in the postgresql.conf file
-in order to use encodings other than ascii. Set this value to the same value as
-the "encoding" parameter on create_engine(), usually "utf-8".
+pg8000 requires that the postgresql client encoding be
+configured in the postgresql.conf file in order to use encodings
+other than ascii. Set this value to the same value as the
+"encoding" parameter on create_engine(), usually "utf-8".
Interval
--------
-Passing data from/to the Interval type is not supported as of yet.
+Passing data from/to the Interval type is not supported as of
+yet.
"""
import decimal
@@ -27,26 +29,28 @@ from sqlalchemy import processors
from sqlalchemy import types as sqltypes
from sqlalchemy.dialects.postgresql.base import PGDialect, \
PGCompiler, PGIdentifierPreparer, PGExecutionContext,\
- _DECIMAL_TYPES, _FLOAT_TYPES
+ _DECIMAL_TYPES, _FLOAT_TYPES, _INT_TYPES
class _PGNumeric(sqltypes.Numeric):
def result_processor(self, dialect, coltype):
if self.asdecimal:
if coltype in _FLOAT_TYPES:
return processors.to_decimal_processor_factory(decimal.Decimal)
- elif coltype in _DECIMAL_TYPES:
+ elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
# pg8000 returns Decimal natively for 1700
return None
else:
- raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+ raise exc.InvalidRequestError(
+ "Unknown PG numeric type: %d" % coltype)
else:
if coltype in _FLOAT_TYPES:
# pg8000 returns float natively for 701
return None
- elif coltype in _DECIMAL_TYPES:
+ elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
return processors.to_float
else:
- raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+ raise exc.InvalidRequestError(
+ "Unknown PG numeric type: %d" % coltype)
class PGExecutionContext_pg8000(PGExecutionContext):
pass
diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py
index 04b4e1fb7..7c5562064 100644
--- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py
+++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py
@@ -96,8 +96,9 @@ from sqlalchemy.sql import expression
from sqlalchemy.sql import operators as sql_operators
from sqlalchemy import types as sqltypes
from sqlalchemy.dialects.postgresql.base import PGDialect, PGCompiler, \
- PGIdentifierPreparer, PGExecutionContext, \
- ENUM, ARRAY, _DECIMAL_TYPES, _FLOAT_TYPES
+ PGIdentifierPreparer, PGExecutionContext, \
+ ENUM, ARRAY, _DECIMAL_TYPES, _FLOAT_TYPES,\
+ _INT_TYPES
logger = logging.getLogger('sqlalchemy.dialects.postgresql')
@@ -111,19 +112,21 @@ class _PGNumeric(sqltypes.Numeric):
if self.asdecimal:
if coltype in _FLOAT_TYPES:
return processors.to_decimal_processor_factory(decimal.Decimal)
- elif coltype in _DECIMAL_TYPES:
+ elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
# pg8000 returns Decimal natively for 1700
return None
else:
- raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+ raise exc.InvalidRequestError(
+ "Unknown PG numeric type: %d" % coltype)
else:
if coltype in _FLOAT_TYPES:
# pg8000 returns float natively for 701
return None
- elif coltype in _DECIMAL_TYPES:
+ elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
return processors.to_float
else:
- raise exc.InvalidRequestError("Unknown PG numeric type: %d" % coltype)
+ raise exc.InvalidRequestError(
+ "Unknown PG numeric type: %d" % coltype)
class _PGEnum(ENUM):
def __init__(self, *arg, **kw):