--- /dev/null
+.. change::
+ :tags: bug, engine
+
+ The :meth:`_engine.Dialect.has_table` method now raises an informative
+ exception if a non-Connection is passed to it, as this incorrect behavior
+ seems to be common. This method is not intended for external use outside
+ of a dialect. Please use the :meth:`.Inspector.has_table` method
+ or for cross-compatibility with older SQLAlchemy versions, the
+ :meth:`_engine.Engine.has_table` method.
+
def has_table(self, connection, table_name, schema=None):
"""Return ``True`` if the given table exists, ignoring
the `schema`."""
+ self._ensure_has_table_connection(connection)
tblqry = """
SELECT 1 AS has_table FROM rdb$database
@_db_plus_owner
def has_table(self, connection, tablename, dbname, owner, schema):
+ self._ensure_has_table_connection(connection)
if tablename.startswith("#"): # temporary table
tables = ischema.mssql_temp_table_columns
return connection.exec_driver_sql("SELECT DATABASE()").scalar()
def has_table(self, connection, table_name, schema=None):
+ self._ensure_has_table_connection(connection)
+
if schema is None:
schema = self.default_schema_name
raise NotImplementedError("implemented by cx_Oracle dialect")
def has_table(self, connection, table_name, schema=None):
+ self._ensure_has_table_connection(connection)
+
if not schema:
schema = self.default_schema_name
cursor = connection.execute(
return bool(cursor.first())
def has_table(self, connection, table_name, schema=None):
+ self._ensure_has_table_connection(connection)
# seems like case gets folded in pg_class...
if schema is None:
cursor = connection.execute(
return [row[0] for row in rs]
def has_table(self, connection, table_name, schema=None):
+ self._ensure_has_table_connection(connection)
+
info = self._get_table_pragma(
connection, "table_info", table_name, schema=schema
)
return [v["name"] for v in views]
def has_table(self, connection, table_name, schema=None):
+ self._ensure_has_table_connection(connection)
+
try:
self.get_table_id(connection, table_name, schema)
except exc.NoSuchTableError:
from . import characteristics
from . import cursor as _cursor
from . import interfaces
+from .base import Connection
from .. import event
from .. import exc
from .. import pool
self._encoder = codecs.getencoder(self.encoding)
self._decoder = processors.to_unicode_processor_factory(self.encoding)
+ def _ensure_has_table_connection(self, arg):
+
+ if not isinstance(arg, Connection):
+ raise exc.ArgumentError(
+ "The argument passed to Dialect.has_table() should be a "
+ "%s, got %s. "
+ "Additionally, the Dialect.has_table() method is for "
+ "internal dialect "
+ "use only; please use "
+ "``inspect(some_engine).has_table(<tablename>>)`` "
+ "for public API use." % (Connection, type(arg))
+ )
+
@util.memoized_property
def _supports_statement_cache(self):
return (
raise NotImplementedError()
def has_table(self, connection, table_name, schema=None, **kw):
- """Check the existence of a particular table in the database.
+ """For internal dialect use, check the existence of a particular table
+ in the database.
+
+ Given a :class:`_engine.Connection` object, a string table_name and
+ optional schema name, return True if the given table exists in the
+ database, False otherwise.
+
+ This method serves as the underlying implementation of the
+ public facing :meth:`.Inspector.has_table` method, and is also used
+ internally to implement the "checkfirst" behavior for methods like
+ :meth:`_schema.Table.create` and :meth:`_schema.MetaData.create_all`.
+
+ .. note:: This method is used internally by SQLAlchemy, and is
+ published so that third-party dialects may provide an
+ implementation. It is **not** the public API for checking for table
+ presence. Please use the :meth:`.Inspector.has_table` method.
+ Alternatively, for legacy cross-compatibility, the
+ :meth:`_engine.Engine.has_table` method may be used.
- Given a :class:`_engine.Connection` object and a string
- `table_name`, return True if the given table (possibly within
- the specified `schema`) exists in the database, False
- otherwise.
"""
raise NotImplementedError()
:param table_name: name of the table to check
:param schema: schema name to query, if not the default schema.
- .. versionadded:: 1.4
+ .. versionadded:: 1.4 - the :meth:`.Inspector.has_table` method
+ replaces the :meth:`_engine.Engine.has_table` method.
"""
# TODO: info_cache?
(4, "sally"),
]
+ def test_dialect_has_table_assertion(self):
+ with expect_raises_message(
+ tsa.exc.ArgumentError,
+ r"The argument passed to Dialect.has_table\(\) should be a",
+ ):
+ testing.db.dialect.has_table(testing.db, "some_table")
+
def test_exception_wrapping_dbapi(self):
with testing.db.connect() as conn:
# engine does not have exec_driver_sql