ydb-sqlalchemy 0.1.20__tar.gz → 0.1.22__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {ydb_sqlalchemy-0.1.20/ydb_sqlalchemy.egg-info → ydb_sqlalchemy-0.1.22}/PKG-INFO +1 -1
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/setup.py +1 -1
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/test/test_inspect.py +29 -0
- ydb_sqlalchemy-0.1.22/ydb_sqlalchemy/_version.py +1 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/__init__.py +4 -14
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/compiler/base.py +8 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22/ydb_sqlalchemy.egg-info}/PKG-INFO +1 -1
- ydb_sqlalchemy-0.1.20/ydb_sqlalchemy/_version.py +0 -1
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/LICENSE +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/MANIFEST.in +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/README.md +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/pyproject.toml +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/requirements.txt +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/setup.cfg +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/test/__init__.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/test/conftest.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/test/test_core.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/test/test_orm.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/test/test_suite.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/__init__.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/compiler/__init__.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/compiler/sa14.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/compiler/sa20.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/datetime_types.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/dbapi_adapter.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/dml.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/json.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/requirements.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/test_sqlalchemy.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/types.py +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy.egg-info/SOURCES.txt +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy.egg-info/dependency_links.txt +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy.egg-info/entry_points.txt +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy.egg-info/requires.txt +0 -0
- {ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy.egg-info/top_level.txt +0 -0
|
@@ -13,7 +13,7 @@ with open("requirements.txt") as f:
|
|
|
13
13
|
|
|
14
14
|
setuptools.setup(
|
|
15
15
|
name="ydb-sqlalchemy",
|
|
16
|
-
version="0.1.
|
|
16
|
+
version="0.1.22", # AUTOVERSION
|
|
17
17
|
description="YDB Dialect for SQLAlchemy",
|
|
18
18
|
author="Yandex LLC",
|
|
19
19
|
author_email="ydb@yandex-team.ru",
|
|
@@ -61,6 +61,35 @@ class TestInspection(TablesTest):
|
|
|
61
61
|
assert inspect.has_table("test")
|
|
62
62
|
assert not inspect.has_table("foo")
|
|
63
63
|
|
|
64
|
+
def test_reflection_ignores_schema(self, connection):
|
|
65
|
+
# supports_schemas=False: the `schema` argument is ignored regardless of value,
|
|
66
|
+
# so reflection always targets the connected database (the convention two-tier
|
|
67
|
+
# SQLAlchemy tooling relies on).
|
|
68
|
+
inspect = sa.inspect(connection)
|
|
69
|
+
bound_database = connection.connection.driver_connection.database.strip("/")
|
|
70
|
+
|
|
71
|
+
for schema in (bound_database, "some_other_database"):
|
|
72
|
+
assert "test" in inspect.get_table_names(schema=schema)
|
|
73
|
+
assert inspect.has_table("test", schema=schema)
|
|
74
|
+
assert inspect.get_columns("test", schema=schema)
|
|
75
|
+
|
|
76
|
+
def test_compile_ignores_schema_prefix(self, connection):
|
|
77
|
+
bound_database = connection.connection.driver_connection.database.strip("/")
|
|
78
|
+
|
|
79
|
+
# A table addressed via the connected database as schema (the way two-tier
|
|
80
|
+
# tooling does) must compile without a schema prefix and execute against YDB.
|
|
81
|
+
t = sa.Table("test", sa.MetaData(), schema=bound_database, autoload_with=connection)
|
|
82
|
+
stmt = sa.select(sa.func.count()).select_from(t)
|
|
83
|
+
compiled = str(stmt.compile(connection))
|
|
84
|
+
assert f"{bound_database}.`test`" not in compiled
|
|
85
|
+
assert f"{bound_database}.test" not in compiled
|
|
86
|
+
connection.execute(stmt).scalar()
|
|
87
|
+
|
|
88
|
+
# Any other schema is likewise dropped rather than leaking into the path.
|
|
89
|
+
foreign = sa.Table("test", sa.MetaData(), Column("id", Integer), schema="some_other_database")
|
|
90
|
+
compiled_foreign = str(sa.select(sa.func.count()).select_from(foreign).compile(connection))
|
|
91
|
+
assert "some_other_database." not in compiled_foreign
|
|
92
|
+
|
|
64
93
|
def test_view_reflection(self, connection, test_view):
|
|
65
94
|
view_name = test_view
|
|
66
95
|
inspect = sa.inspect(connection)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.1.22"
|
|
@@ -250,13 +250,9 @@ class YqlDialect(StrCompileDialect):
|
|
|
250
250
|
self._add_declare_for_yql_stmt_vars = _add_declare_for_yql_stmt_vars
|
|
251
251
|
self._statement_prefixes = tuple(_statement_prefixes_list) if _statement_prefixes_list else ()
|
|
252
252
|
|
|
253
|
-
def _ensure_schema_unsupported(self, schema):
|
|
254
|
-
if schema:
|
|
255
|
-
raise ydb_dbapi.NotSupportedError("unsupported on non empty schema")
|
|
256
|
-
|
|
257
253
|
def _describe_table(self, connection, table_name, schema=None) -> ydb.TableDescription:
|
|
258
|
-
|
|
259
|
-
|
|
254
|
+
# supports_schemas=False: the schema argument is ignored, reflection always
|
|
255
|
+
# targets the connected database.
|
|
260
256
|
qt = table_name if isinstance(table_name, str) else table_name.name
|
|
261
257
|
raw_conn = connection.connection
|
|
262
258
|
try:
|
|
@@ -265,16 +261,12 @@ class YqlDialect(StrCompileDialect):
|
|
|
265
261
|
raise NoSuchTableError(qt) from e
|
|
266
262
|
|
|
267
263
|
@reflection.cache
|
|
268
|
-
def get_view_names(self, connection, schema=None, **kw
|
|
269
|
-
self._ensure_schema_unsupported(schema)
|
|
270
|
-
|
|
264
|
+
def get_view_names(self, connection, schema=None, **kw):
|
|
271
265
|
raw_conn = connection.connection
|
|
272
266
|
return raw_conn.get_view_names()
|
|
273
267
|
|
|
274
268
|
@reflection.cache
|
|
275
|
-
def get_view_definition(self, connection, view_name, schema=None, **kw
|
|
276
|
-
self._ensure_schema_unsupported(schema)
|
|
277
|
-
|
|
269
|
+
def get_view_definition(self, connection, view_name, schema=None, **kw):
|
|
278
270
|
quoted_view_name = self.identifier_preparer.quote(view_name)
|
|
279
271
|
result = connection.execute(sa.text(f"SHOW CREATE VIEW {quoted_view_name}"))
|
|
280
272
|
row = result.fetchone()
|
|
@@ -301,8 +293,6 @@ class YqlDialect(StrCompileDialect):
|
|
|
301
293
|
|
|
302
294
|
@reflection.cache
|
|
303
295
|
def get_table_names(self, connection, schema=None, **kw):
|
|
304
|
-
self._ensure_schema_unsupported(schema)
|
|
305
|
-
|
|
306
296
|
raw_conn = connection.connection
|
|
307
297
|
return raw_conn.get_table_names()
|
|
308
298
|
|
|
@@ -270,6 +270,10 @@ class BaseYqlCompiler(StrSQLCompiler):
|
|
|
270
270
|
def get_from_hint_text(self, table, text):
|
|
271
271
|
return text
|
|
272
272
|
|
|
273
|
+
def visit_table(self, table, use_schema=True, **kwargs):
|
|
274
|
+
# supports_schemas=False: never emit a schema qualifier in FROM/hint clauses.
|
|
275
|
+
return super().visit_table(table, use_schema=False, **kwargs)
|
|
276
|
+
|
|
273
277
|
def group_by_clause(self, select, **kw):
|
|
274
278
|
# Hack to ensure it is possible to define labels in groupby.
|
|
275
279
|
kw.update(within_columns_clause=True)
|
|
@@ -530,5 +534,9 @@ class BaseYqlIdentifierPreparer(IdentifierPreparer):
|
|
|
530
534
|
final_quote="`",
|
|
531
535
|
)
|
|
532
536
|
|
|
537
|
+
def format_table(self, table, use_schema=True, name=None):
|
|
538
|
+
# supports_schemas=False: never emit a schema qualifier in DML/DDL.
|
|
539
|
+
return super().format_table(table, use_schema=False, name=name)
|
|
540
|
+
|
|
533
541
|
def format_index(self, index: sa.Index) -> str:
|
|
534
542
|
return super().format_index(index).replace("/", "_")
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "0.1.20"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/compiler/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy/sqlalchemy/test_sqlalchemy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ydb_sqlalchemy-0.1.20 → ydb_sqlalchemy-0.1.22}/ydb_sqlalchemy.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|