--- /dev/null
+.. change::
+ :tags: usecase, postgresql
+ :tickets: 8491
+
+ The "ping" query emitted when configuring
+ :paramref:`_sa.create_engine.pool_pre_ping` for psycopg, asyncpg and
+ pg8000, but not for psycopg2, has been changed to be an empty query (``;``)
+ instead of ``SELECT 1``; additionally, for the asyncpg driver, the
+ unnecessary use of a prepared statement for this query has been fixed.
+ Rationale is to eliminate the need for PostgreSQL to produce a query plan
+ when the ping is emitted. The operation is not currently supported by the
+ ``psycopg2`` driver which continues to use ``SELECT 1``.
\ No newline at end of file
else:
self.isolation_level = self._isolation_setting
+ def ping(self):
+ try:
+ _ = self.await_(self._connection.fetchrow(";"))
+ except Exception as error:
+ self._handle_exception(error)
+
def set_isolation_level(self, level):
if self._started:
self.rollback()
util.coerce_kw_type(opts, "port", int)
return ([], opts)
+ def do_ping(self, dbapi_connection):
+ try:
+ dbapi_connection.ping()
+ except self.dbapi.Error as err:
+ if self.is_disconnect(err, dbapi_connection, None):
+ return False
+ else:
+ raise
+ else:
+ return True
+
@classmethod
def get_pool_class(cls, url):
else:
return None
+ @util.memoized_property
+ def _dialect_specific_select_one(self):
+ return ";"
+
dialect = PGDialect_pg8000
else:
self.do_commit(connection.connection)
+ @util.memoized_property
+ def _dialect_specific_select_one(self):
+ return ";"
+
class AsyncAdapt_psycopg_cursor:
__slots__ = ("_cursor", "await_", "_rows")
from .. import engines
from .. import eq_
from .. import fixtures
+from .. import is_true
from .. import ne_
from .. import provide_metadata
from ..assertions import expect_raises_message
from ... import String
+class PingTest(fixtures.TestBase):
+ __backend__ = True
+
+ def test_do_ping(self):
+ with testing.db.connect() as conn:
+ is_true(
+ testing.db.dialect.do_ping(conn.connection.dbapi_connection)
+ )
+
+
class ExceptionTest(fixtures.TablesTest):
"""Test basic exception wrapping.