diff --git a/cratedb_toolkit/model.py b/cratedb_toolkit/model.py index 754bb48..f5546db 100644 --- a/cratedb_toolkit/model.py +++ b/cratedb_toolkit/model.py @@ -4,7 +4,7 @@ from boltons.urlutils import URL -from cratedb_toolkit.util.database import decode_database_table +from cratedb_toolkit.util.database import DatabaseAdapter, decode_database_table @dataclasses.dataclass @@ -85,12 +85,10 @@ class TableAddress: @property def fullname(self): - if self.schema is None and self.table is None: - raise ValueError("Uninitialized table address can not be serialized") - if self.schema and self.table: - return f'"{self.schema}"."{self.table}"' - else: - return f'"{self.table}"' + """ + Return a full-qualified quoted table identifier. + """ + return DatabaseAdapter.quote_relation_name(f"{self.schema}.{self.table}") @dataclasses.dataclass diff --git a/cratedb_toolkit/util/database.py b/cratedb_toolkit/util/database.py index 26eaed7..6b04afe 100644 --- a/cratedb_toolkit/util/database.py +++ b/cratedb_toolkit/util/database.py @@ -11,6 +11,7 @@ from cratedb_sqlparse import sqlparse as sqlparse_cratedb from sqlalchemy.exc import ProgrammingError from sqlalchemy.sql.elements import AsBoolean +from sqlalchemy_cratedb.dialect import CrateDialect from cratedb_toolkit.util.data import str_contains @@ -24,6 +25,10 @@ def run_sql(dburi: str, sql: str, records: bool = False): return DatabaseAdapter(dburi=dburi).run_sql(sql=sql, records=records) +# Just an instance of the dialect used for quoting purposes. +dialect = CrateDialect() + + class DatabaseAdapter: """ Wrap SQLAlchemy connection to database. @@ -35,7 +40,8 @@ def __init__(self, dburi: str, echo: bool = False): # TODO: Make that go away. self.connection = self.engine.connect() - def quote_relation_name(self, ident: str) -> str: + @staticmethod + def quote_relation_name(ident: str) -> str: """ Quote the given, possibly full-qualified, relation name if needed. @@ -61,11 +67,9 @@ def quote_relation_name(self, ident: str) -> str: if len(parts) > 2: raise ValueError(f"Invalid relation name {ident}") return ( - self.engine.dialect.identifier_preparer.quote_schema(parts[0]) - + "." - + self.engine.dialect.identifier_preparer.quote(parts[1]) + dialect.identifier_preparer.quote_schema(parts[0]) + "." + dialect.identifier_preparer.quote(parts[1]) ) - return self.engine.dialect.identifier_preparer.quote(ident=ident) + return dialect.identifier_preparer.quote(ident=ident) def run_sql( self,