summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql/psycopg2.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql/psycopg2.py')
-rw-r--r--lib/sqlalchemy/dialects/postgresql/psycopg2.py163
1 files changed, 8 insertions, 155 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py
index 39b6e0ed1..3d9f90a29 100644
--- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py
+++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py
@@ -11,6 +11,8 @@ r"""
:connectstring: postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]
:url: https://pypi.org/project/psycopg2/
+.. _psycopg2_toplevel:
+
psycopg2 Connect Arguments
--------------------------
@@ -442,25 +444,15 @@ which may be more performant.
""" # noqa
import collections.abc as collections_abc
-import decimal
import logging
import re
-from uuid import UUID as _python_UUID
-from .array import ARRAY as PGARRAY
-from .base import _DECIMAL_TYPES
-from .base import _FLOAT_TYPES
-from .base import _INT_TYPES
+from ._psycopg_common import _PGDialect_common_psycopg
+from ._psycopg_common import _PGExecutionContext_common_psycopg
from .base import PGCompiler
-from .base import PGDialect
-from .base import PGExecutionContext
from .base import PGIdentifierPreparer
-from .base import UUID
-from .hstore import HSTORE
from .json import JSON
from .json import JSONB
-from ... import exc
-from ... import processors
from ... import types as sqltypes
from ... import util
from ...engine import cursor as _cursor
@@ -469,53 +461,6 @@ from ...engine import cursor as _cursor
logger = logging.getLogger("sqlalchemy.dialects.postgresql")
-class _PGNumeric(sqltypes.Numeric):
- def bind_processor(self, dialect):
- return None
-
- def result_processor(self, dialect, coltype):
- if self.asdecimal:
- if coltype in _FLOAT_TYPES:
- return processors.to_decimal_processor_factory(
- decimal.Decimal, self._effective_decimal_return_scale
- )
- 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
- )
- else:
- if coltype in _FLOAT_TYPES:
- # pg8000 returns float natively for 701
- return None
- elif coltype in _DECIMAL_TYPES or coltype in _INT_TYPES:
- return processors.to_float
- else:
- raise exc.InvalidRequestError(
- "Unknown PG numeric type: %d" % coltype
- )
-
-
-class _PGHStore(HSTORE):
- def bind_processor(self, dialect):
- if dialect._has_native_hstore:
- return None
- else:
- return super(_PGHStore, self).bind_processor(dialect)
-
- def result_processor(self, dialect, coltype):
- if dialect._has_native_hstore:
- return None
- else:
- return super(_PGHStore, self).result_processor(dialect, coltype)
-
-
-class _PGARRAY(PGARRAY):
- render_bind_cast = True
-
-
class _PGJSON(JSON):
def result_processor(self, dialect, coltype):
return None
@@ -526,40 +471,9 @@ class _PGJSONB(JSONB):
return None
-class _PGUUID(UUID):
- def bind_processor(self, dialect):
- if not self.as_uuid and dialect.use_native_uuid:
-
- def process(value):
- if value is not None:
- value = _python_UUID(value)
- return value
-
- return process
-
- def result_processor(self, dialect, coltype):
- if not self.as_uuid and dialect.use_native_uuid:
-
- def process(value):
- if value is not None:
- value = str(value)
- return value
-
- return process
-
-
-_server_side_id = util.counter()
-
-
-class PGExecutionContext_psycopg2(PGExecutionContext):
+class PGExecutionContext_psycopg2(_PGExecutionContext_common_psycopg):
_psycopg2_fetched_rows = None
- def create_server_side_cursor(self):
- # use server-side cursors:
- # https://lists.initd.org/pipermail/psycopg/2007-January/005251.html
- ident = "c_%s_%s" % (hex(id(self))[2:], hex(_server_side_id())[2:])
- return self._dbapi_connection.cursor(ident)
-
def post_exec(self):
if (
self._psycopg2_fetched_rows
@@ -614,7 +528,7 @@ EXECUTEMANY_VALUES_PLUS_BATCH = util.symbol(
)
-class PGDialect_psycopg2(PGDialect):
+class PGDialect_psycopg2(_PGDialect_common_psycopg):
driver = "psycopg2"
supports_statement_cache = True
@@ -631,34 +545,22 @@ class PGDialect_psycopg2(PGDialect):
_has_native_hstore = True
colspecs = util.update_copy(
- PGDialect.colspecs,
+ _PGDialect_common_psycopg.colspecs,
{
- sqltypes.Numeric: _PGNumeric,
- HSTORE: _PGHStore,
JSON: _PGJSON,
sqltypes.JSON: _PGJSON,
JSONB: _PGJSONB,
- UUID: _PGUUID,
- sqltypes.ARRAY: _PGARRAY,
},
)
def __init__(
self,
- client_encoding=None,
- use_native_hstore=True,
- use_native_uuid=True,
executemany_mode="values_only",
executemany_batch_page_size=100,
executemany_values_page_size=1000,
**kwargs
):
- PGDialect.__init__(self, **kwargs)
- if not use_native_hstore:
- self._has_native_hstore = False
- self.use_native_hstore = use_native_hstore
- self.use_native_uuid = use_native_uuid
- self.client_encoding = client_encoding
+ _PGDialect_common_psycopg.__init__(self, **kwargs)
# Parse executemany_mode argument, allowing it to be only one of the
# symbol names
@@ -737,9 +639,6 @@ class PGDialect_psycopg2(PGDialect):
"SERIALIZABLE": extensions.ISOLATION_LEVEL_SERIALIZABLE,
}
- def get_isolation_level_values(self, dbapi_conn):
- return list(self._isolation_lookup)
-
def set_isolation_level(self, connection, level):
connection.set_isolation_level(self._isolation_lookup[level])
@@ -755,25 +654,6 @@ class PGDialect_psycopg2(PGDialect):
def get_deferrable(self, connection):
return connection.deferrable
- def do_ping(self, dbapi_connection):
- cursor = None
- try:
- dbapi_connection.autocommit = True
- cursor = dbapi_connection.cursor()
- try:
- cursor.execute(self._dialect_specific_select_one)
- finally:
- cursor.close()
- if not dbapi_connection.closed:
- dbapi_connection.autocommit = False
- except self.dbapi.Error as err:
- if self.is_disconnect(err, dbapi_connection, cursor):
- return False
- else:
- raise
- else:
- return True
-
def on_connect(self):
extras = self._psycopg2_extras
@@ -911,33 +791,6 @@ class PGDialect_psycopg2(PGDialect):
else:
return None
- def create_connect_args(self, url):
- opts = url.translate_connect_args(username="user")
-
- is_multihost = False
- if "host" in url.query:
- is_multihost = isinstance(url.query["host"], (list, tuple))
-
- if opts:
- if "port" in opts:
- opts["port"] = int(opts["port"])
- opts.update(url.query)
- if is_multihost:
- opts["host"] = ",".join(url.query["host"])
- # send individual dbname, user, password, host, port
- # parameters to psycopg2.connect()
- return ([], opts)
- elif url.query:
- # any other connection arguments, pass directly
- opts.update(url.query)
- if is_multihost:
- opts["host"] = ",".join(url.query["host"])
- return ([], opts)
- else:
- # no connection arguments whatsoever; psycopg2.connect()
- # requires that "dsn" be present as a blank string.
- return ([""], opts)
-
def is_disconnect(self, e, connection, cursor):
if isinstance(e, self.dbapi.Error):
# check the "closed" flag. this might not be