Skip to content

Commit 808109f

Browse files
authored
Merge pull request #23 from ydb-platform/get_view_names
Ability to get view names
2 parents ac0cb5d + df67b77 commit 808109f

File tree

5 files changed

+104
-14
lines changed

5 files changed

+104
-14
lines changed

examples/basic_example.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import ydb_dbapi as dbapi
2+
3+
4+
def main() -> None:
5+
connection = dbapi.connect(
6+
host="localhost",
7+
port=2136,
8+
database="/local",
9+
)
10+
11+
print(f"Existing tables: {connection.get_table_names()}")
12+
print(f"Existing views: {connection.get_view_names()}")
13+
# TODO: fill example
14+
15+
connection.close()
16+
17+
18+
if __name__ == "__main__":
19+
main()

poetry.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repository = "https://github.com/ydb-platform/ydb-python-dbapi/"
88

99
[tool.poetry.dependencies]
1010
python = "^3.8"
11-
ydb = "^3.18.13"
11+
ydb = "^3.18.16"
1212

1313
[tool.poetry.group.dev.dependencies]
1414
pre-commit = "^3.5.0"
@@ -78,6 +78,7 @@ force-single-line = true
7878

7979
[tool.ruff.lint.per-file-ignores]
8080
"**/test_*.py" = ["S", "SLF", "ANN201", "ARG", "PLR2004", "PT012"]
81+
"examples/*.py" = ["T201", "INP001"]
8182
"conftest.py" = ["S", "ARG001"]
8283
"__init__.py" = ["F401", "F403"]
8384

tests/test_connections.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,41 @@ def _test_error_with_interactive_tx(
239239
maybe_await(cur.close())
240240
maybe_await(connection.rollback())
241241

242+
def _test_get_view_names(
243+
self,
244+
connection: dbapi.Connection,
245+
) -> None:
246+
cur = connection.cursor()
247+
248+
maybe_await(
249+
cur.execute_scheme(
250+
"""
251+
DROP VIEW if exists test_view;
252+
"""
253+
)
254+
)
255+
256+
res = maybe_await(connection.get_view_names())
257+
258+
assert len(res) == 0
259+
260+
maybe_await(
261+
cur.execute_scheme(
262+
"""
263+
CREATE VIEW test_view WITH (security_invoker = TRUE) as (
264+
select 1 as res
265+
);
266+
"""
267+
)
268+
)
269+
270+
res = maybe_await(connection.get_view_names())
271+
272+
assert len(res) == 1
273+
assert res[0] == "test_view"
274+
275+
maybe_await(cur.close())
276+
242277

243278
class TestConnection(BaseDBApiTestSuit):
244279
@pytest.fixture
@@ -289,6 +324,11 @@ def test_errors_with_interactive_tx(
289324
) -> None:
290325
self._test_error_with_interactive_tx(connection)
291326

327+
def test_get_view_names(
328+
self, connection: dbapi.Connection
329+
) -> None:
330+
self._test_get_view_names(connection)
331+
292332

293333
class TestAsyncConnection(BaseDBApiTestSuit):
294334
@pytest_asyncio.fixture
@@ -358,3 +398,9 @@ async def test_errors_with_interactive_tx(
358398
self, connection: dbapi.AsyncConnection
359399
) -> None:
360400
await greenlet_spawn(self._test_error_with_interactive_tx, connection)
401+
402+
@pytest.mark.asyncio
403+
async def test_get_view_names(
404+
self, connection: dbapi.AsyncConnection
405+
) -> None:
406+
await greenlet_spawn(self._test_get_view_names, connection)

ydb_dbapi/connections.py

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,13 @@ def check_exists(self, table_path: str) -> bool:
277277
@handle_ydb_errors
278278
def get_table_names(self) -> list[str]:
279279
abs_dir_path = posixpath.join(self.database, self.table_path_prefix)
280-
names = self._get_table_names(abs_dir_path)
280+
names = self._get_entity_names(abs_dir_path, ydb.SchemeEntryType.TABLE)
281+
return [posixpath.relpath(path, abs_dir_path) for path in names]
282+
283+
@handle_ydb_errors
284+
def get_view_names(self) -> list[str]:
285+
abs_dir_path = posixpath.join(self.database, self.table_path_prefix)
286+
names = self._get_entity_names(abs_dir_path, ydb.SchemeEntryType.VIEW)
281287
return [posixpath.relpath(path, abs_dir_path) for path in names]
282288

283289
def _check_path_exists(self, table_path: str) -> bool:
@@ -295,7 +301,9 @@ def callee() -> None:
295301
else:
296302
return True
297303

298-
def _get_table_names(self, abs_dir_path: str) -> list[str]:
304+
def _get_entity_names(
305+
self, abs_dir_path: str, etype: ydb.SchemeEntryType
306+
) -> list[str]:
299307
settings = self._get_request_settings()
300308

301309
def callee() -> ydb.Directory:
@@ -308,10 +316,10 @@ def callee() -> ydb.Directory:
308316
result = []
309317
for child in directory.children:
310318
child_abs_path = posixpath.join(abs_dir_path, child.name)
311-
if child.is_table():
319+
if child.type == etype:
312320
result.append(child_abs_path)
313321
elif child.is_directory() and not child.name.startswith("."):
314-
result.extend(self._get_table_names(child_abs_path))
322+
result.extend(self._get_entity_names(child_abs_path, etype))
315323
return result
316324

317325
@handle_ydb_errors
@@ -452,7 +460,19 @@ async def check_exists(self, table_path: str) -> bool:
452460
@handle_ydb_errors
453461
async def get_table_names(self) -> list[str]:
454462
abs_dir_path = posixpath.join(self.database, self.table_path_prefix)
455-
names = await self._get_table_names(abs_dir_path)
463+
names = await self._get_entity_names(
464+
abs_dir_path,
465+
ydb.SchemeEntryType.TABLE,
466+
)
467+
return [posixpath.relpath(path, abs_dir_path) for path in names]
468+
469+
@handle_ydb_errors
470+
async def get_view_names(self) -> list[str]:
471+
abs_dir_path = posixpath.join(self.database, self.table_path_prefix)
472+
names = await self._get_entity_names(
473+
abs_dir_path,
474+
ydb.SchemeEntryType.VIEW,
475+
)
456476
return [posixpath.relpath(path, abs_dir_path) for path in names]
457477

458478
async def _check_path_exists(self, table_path: str) -> bool:
@@ -471,7 +491,9 @@ async def callee() -> None:
471491
else:
472492
return True
473493

474-
async def _get_table_names(self, abs_dir_path: str) -> list[str]:
494+
async def _get_entity_names(
495+
self, abs_dir_path: str, etype: ydb.SchemeEntryType
496+
) -> list[str]:
475497
settings = self._get_request_settings()
476498

477499
async def callee() -> ydb.Directory:
@@ -484,10 +506,12 @@ async def callee() -> ydb.Directory:
484506
result = []
485507
for child in directory.children:
486508
child_abs_path = posixpath.join(abs_dir_path, child.name)
487-
if child.is_table():
509+
if child.type == etype:
488510
result.append(child_abs_path)
489511
elif child.is_directory() and not child.name.startswith("."):
490-
result.extend(await self._get_table_names(child_abs_path))
512+
result.extend(
513+
await self._get_entity_names(child_abs_path, etype)
514+
)
491515
return result
492516

493517
@handle_ydb_errors

0 commit comments

Comments
 (0)