Skip to content

Commit 737be0e

Browse files
authored
Merge branch 'main' into feat/ydb-secondary-indicies
2 parents 83fe8e5 + 6dc5578 commit 737be0e

File tree

6 files changed

+77
-3
lines changed

6 files changed

+77
-3
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
* Added declare for yql statement variables (opt in) - temporary flag
2+
3+
## 0.0.1b12 ##
4+
* supported ydb connection credentials
5+
16
## 0.0.1b11 ##
27
* test release
38

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
setuptools.setup(
1515
name="ydb-sqlalchemy",
16-
version="0.0.1b11", # AUTOVERSION
16+
version="0.0.1b12", # AUTOVERSION
1717
description="YDB Dialect for SQLAlchemy",
1818
author="Yandex LLC",
1919
author_email="ydb@yandex-team.ru",

test/test_core.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ def test_sa_crud(self, connection):
8383
(5, "c"),
8484
]
8585

86+
def test_sa_crud_with_add_declare(self):
87+
engine = sa.create_engine(config.db_url, _add_declare_for_yql_stmt_vars=True)
88+
with engine.connect() as connection:
89+
self.test_sa_crud(connection)
90+
8691

8792
class TestSimpleSelect(TablesTest):
8893
__backend__ = True
@@ -597,6 +602,57 @@ def ydb_pool(self, ydb_driver):
597602
loop.run_until_complete(session_pool.stop())
598603

599604

605+
class TestCredentials(TestBase):
606+
__backend__ = True
607+
__only_on__ = "yql+ydb"
608+
609+
@pytest.fixture(scope="class")
610+
def table_client_settings(self):
611+
yield (
612+
ydb.TableClientSettings()
613+
.with_native_date_in_result_sets(True)
614+
.with_native_datetime_in_result_sets(True)
615+
.with_native_timestamp_in_result_sets(True)
616+
.with_native_interval_in_result_sets(True)
617+
.with_native_json_in_result_sets(False)
618+
)
619+
620+
@pytest.fixture(scope="class")
621+
def driver_config_for_credentials(self, table_client_settings):
622+
url = config.db_url
623+
endpoint = f"grpc://{url.host}:{url.port}"
624+
database = url.database
625+
626+
yield ydb.DriverConfig(
627+
endpoint=endpoint,
628+
database=database,
629+
table_client_settings=table_client_settings,
630+
)
631+
632+
def test_ydb_credentials_good(self, table_client_settings, driver_config_for_credentials):
633+
credentials_good = ydb.StaticCredentials(
634+
driver_config=driver_config_for_credentials,
635+
user="root",
636+
password="1234",
637+
)
638+
engine = sa.create_engine(config.db_url, connect_args={"credentials": credentials_good})
639+
with engine.connect() as conn:
640+
result = conn.execute(sa.text("SELECT 1 as value"))
641+
assert result.fetchone()
642+
643+
def test_ydb_credentials_bad(self, table_client_settings, driver_config_for_credentials):
644+
credentials_bad = ydb.StaticCredentials(
645+
driver_config=driver_config_for_credentials,
646+
user="root",
647+
password="56",
648+
)
649+
engine = sa.create_engine(config.db_url, connect_args={"credentials": credentials_bad})
650+
with pytest.raises(Exception) as excinfo:
651+
with engine.connect() as conn:
652+
conn.execute(sa.text("SELECT 1 as value"))
653+
assert "Invalid password" in str(excinfo.value)
654+
655+
600656
class TestUpsert(TablesTest):
601657
__backend__ = True
602658

ydb_sqlalchemy/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION = "0.0.1b11"
1+
VERSION = "0.0.1b12"

ydb_sqlalchemy/dbapi/connection.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def __init__(
3737
self.endpoint = f"grpc://{host}:{port}"
3838
self.database = database
3939
self.conn_kwargs = conn_kwargs
40+
self.credentials = self.conn_kwargs.pop("credentials", None)
4041

4142
if "ydb_session_pool" in self.conn_kwargs: # Use session pool managed manually
4243
self._shared_session_pool = True
@@ -157,6 +158,7 @@ def _create_driver(self):
157158
endpoint=self.endpoint,
158159
database=self.database,
159160
table_client_settings=self._get_table_client_settings(),
161+
credentials=self.credentials,
160162
)
161163
driver = self._ydb_driver_class(driver_config)
162164
try:

ydb_sqlalchemy/sqlalchemy/__init__.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,11 +625,14 @@ class YqlDialect(StrCompileDialect):
625625
def import_dbapi(cls: Any):
626626
return dbapi.YdbDBApi()
627627

628-
def __init__(self, json_serializer=None, json_deserializer=None, **kwargs):
628+
def __init__(self, json_serializer=None, json_deserializer=None, _add_declare_for_yql_stmt_vars=False, **kwargs):
629629
super().__init__(**kwargs)
630630

631631
self._json_deserializer = json_deserializer
632632
self._json_serializer = json_serializer
633+
# NOTE: _add_declare_for_yql_stmt_vars is temporary and is soon to be removed.
634+
# no need in declare in yql statement here since ydb 24-1
635+
self._add_declare_for_yql_stmt_vars = _add_declare_for_yql_stmt_vars
633636

634637
def _describe_table(self, connection, table_name, schema=None) -> ydb.TableDescription:
635638
if schema is not None:
@@ -752,6 +755,12 @@ def _format_variables(
752755
formatted_statement = formatted_statement.replace("%%", "%")
753756
return formatted_statement, formatted_parameters
754757

758+
def _add_declare_for_yql_stmt_vars_impl(self, statement, parameters_types):
759+
declarations = "\n".join(
760+
[f"DECLARE {param_name} as {str(param_type)};" for param_name, param_type in parameters_types.items()]
761+
)
762+
return f"{declarations}\n{statement}"
763+
755764
def _make_ydb_operation(
756765
self,
757766
statement: str,
@@ -765,6 +774,8 @@ def _make_ydb_operation(
765774
parameters_types = context.compiled.get_bind_types(parameters)
766775
parameters_types = {f"${k}": v for k, v in parameters_types.items()}
767776
statement, parameters = self._format_variables(statement, parameters, execute_many)
777+
if self._add_declare_for_yql_stmt_vars:
778+
statement = self._add_declare_for_yql_stmt_vars_impl(statement, parameters_types)
768779
return dbapi.YdbQuery(yql_text=statement, parameters_types=parameters_types, is_ddl=is_ddl), parameters
769780

770781
statement, parameters = self._format_variables(statement, parameters, execute_many)

0 commit comments

Comments
 (0)