diff --git a/CHANGES.md b/CHANGES.md index 2e2da416..34f45013 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,7 @@ # Changelog - ## Unreleased +- Added `quote_relation_name` support utility function ## 2024/06/25 0.38.0 - Added/reactivated documentation as `sqlalchemy-cratedb` diff --git a/pyproject.toml b/pyproject.toml index 1b4ddead..26eee6b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -280,7 +280,7 @@ lint = [ { cmd = "ruff format --check" }, { cmd = "ruff check" }, { cmd = "validate-pyproject pyproject.toml" }, - # { cmd = "mypy" }, + { cmd = "mypy" }, ] release = [ diff --git a/src/sqlalchemy_cratedb/compat/api13.py b/src/sqlalchemy_cratedb/compat/api13.py index 6b19dc8a..1d7985a0 100644 --- a/src/sqlalchemy_cratedb/compat/api13.py +++ b/src/sqlalchemy_cratedb/compat/api13.py @@ -34,6 +34,7 @@ """ import collections.abc as collections_abc +import typing as t from sqlalchemy import exc from sqlalchemy.sql import Select @@ -42,7 +43,7 @@ # `_distill_params_20` copied from SA14's `sqlalchemy.engine.{base,util}`. _no_tuple = () -_no_kw = immutabledict() +_no_kw: immutabledict = immutabledict() def _distill_params_20(params): @@ -87,11 +88,11 @@ def monkeypatch_add_exec_driver_sql(): from sqlalchemy.engine.base import Connection, Engine # Add `exec_driver_sql` method to SA's `Connection` and `Engine` classes. - Connection.exec_driver_sql = exec_driver_sql - Engine.exec_driver_sql = exec_driver_sql + Connection.exec_driver_sql = exec_driver_sql # type: ignore[method-assign] + Engine.exec_driver_sql = exec_driver_sql # type: ignore[attr-defined] -def select_sa14(*columns, **kw) -> Select: +def select_sa14(*columns, **kw) -> Select[t.Any]: """ Adapt SA14/SA20's calling semantics of `sql.select()` to SA13. diff --git a/src/sqlalchemy_cratedb/support/__init__.py b/src/sqlalchemy_cratedb/support/__init__.py index 673f7121..2721c364 100644 --- a/src/sqlalchemy_cratedb/support/__init__.py +++ b/src/sqlalchemy_cratedb/support/__init__.py @@ -4,12 +4,13 @@ patch_autoincrement_timestamp, refresh_after_dml, ) -from sqlalchemy_cratedb.support.util import refresh_dirty, refresh_table +from sqlalchemy_cratedb.support.util import quote_relation_name, refresh_dirty, refresh_table __all__ = [ check_uniqueness_factory, insert_bulk, patch_autoincrement_timestamp, + quote_relation_name, refresh_after_dml, refresh_dirty, refresh_table, diff --git a/src/sqlalchemy_cratedb/support/util.py b/src/sqlalchemy_cratedb/support/util.py index 9b9b07f9..c66e67ea 100644 --- a/src/sqlalchemy_cratedb/support/util.py +++ b/src/sqlalchemy_cratedb/support/util.py @@ -3,6 +3,8 @@ import sqlalchemy as sa +from sqlalchemy_cratedb.dialect import CrateDialect + if t.TYPE_CHECKING: try: from sqlalchemy.orm import DeclarativeBase @@ -10,6 +12,10 @@ pass +# An instance of the dialect used for quoting purposes. +identifier_preparer = CrateDialect().identifier_preparer + + def refresh_table( connection, target: t.Union[str, "DeclarativeBase", "sa.sql.selectable.TableClause"] ): @@ -41,3 +47,36 @@ def refresh_dirty(session, flush_context=None): dirty_classes = {entity.__class__ for entity in dirty_entities} for class_ in dirty_classes: refresh_table(session, class_) + + +def quote_relation_name(ident: str) -> str: + """ + Quote a simple or full-qualified table/relation name, when needed. + + Simple: