diff --git a/docs/supported-databases/oracle.rst b/docs/supported-databases/oracle.rst index 5ceae26..b38f44a 100644 --- a/docs/supported-databases/oracle.rst +++ b/docs/supported-databases/oracle.rst @@ -22,6 +22,8 @@ Usage Example pytest_plugins = ["pytest_databases.docker.oracle"] def test(oracle_service: OracleService) -> None: + # ``oracledb`` is user-owned application code; pytest-databases only + # starts the service and provides connection metadata. conn = oracledb.connect( user=oracle_service.user, password=oracle_service.password, @@ -34,24 +36,18 @@ Usage Example res = cur.fetchone()[0] assert res == 1 - def test(oracle_startup_connection: oracledb.Connection) -> None: - with oracle_startup_connection.cursor() as cursor: - cursor.execute("CREATE or replace view simple_table as SELECT 1 as the_value from dual") - cursor.execute("select * from simple_table") - result = cursor.fetchall() - assert result is not None and result[0][0] == 1 - Available Fixtures ------------------ -* ``oracle_image``: The Docker image to use for Oracle. -* ``oracle_service``: A fixture that provides an Oracle service. -* ``oracle_startup_connection``: A fixture that provides an Oracle connection. +* ``oracle_user``: The application username created in the Oracle container. +* ``oracle_password``: The application user password. +* ``oracle_system_password``: The Oracle system password. +* ``oracle_service``: Alias for the latest supported Oracle service. The following version-specific fixtures are also available: -* ``oracle_18c_image``, ``oracle_18c_service_name``, ``oracle_18c_service``, ``oracle_18c_connection``: Oracle 18c -* ``oracle_23ai_image``, ``oracle_23ai_service_name``, ``oracle_23ai_service``, ``oracle_23ai_connection``: Oracle 23ai +* ``oracle_18c_image``, ``oracle_18c_service_name``, ``oracle_18c_service``: Oracle 18c +* ``oracle_23ai_image``, ``oracle_23ai_service_name``, ``oracle_23ai_service``: Oracle 23ai Service API ----------- diff --git a/pyproject.toml b/pyproject.toml index af70e1f..45f827e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,7 +71,7 @@ mariadb = [] mongodb = ["pymongo"] mssql = [] mysql = [] -oracle = ["oracledb"] +oracle = [] postgres = ["psycopg>=3"] redis = ["redis"] spanner = ["google-cloud-spanner"] @@ -385,7 +385,9 @@ line-length = 120 [tool.pytest.ini_options] addopts = "--doctest-glob='*.md' --dist=loadgroup" -cdist-group-steal = "3:10" +# Keep the middle shard non-empty when file justification moves a large test file +# across cdist chunk boundaries. pytest-cdist 0.3.x accepts only one steal entry. +cdist-group-steal = "2:10" cdist-justify-items = "file" filterwarnings = [ "ignore::DeprecationWarning:pkg_resources", diff --git a/src/pytest_databases/docker/oracle.py b/src/pytest_databases/docker/oracle.py index 9ff9a8a..8a4d81c 100644 --- a/src/pytest_databases/docker/oracle.py +++ b/src/pytest_databases/docker/oracle.py @@ -1,36 +1,62 @@ from __future__ import annotations import contextlib +import shlex from dataclasses import dataclass from typing import TYPE_CHECKING -import oracledb import pytest from pytest_databases.helpers import get_xdist_worker_num from pytest_databases.types import ServiceContainer if TYPE_CHECKING: - from collections.abc import Generator + from collections.abc import Generator, Iterator + + from docker.models.containers import Container from pytest_databases._service import DockerService -def oracle_responsive(host: str, port: int, service_name: str, user: str, password: str) -> bool: - try: - conn = oracledb.connect( - host=host, - port=port, - user=user, - service_name=service_name, - password=password, - ) - with conn.cursor() as cursor: - cursor.execute("SELECT 1 FROM dual") - resp = cursor.fetchone() - return resp[0] == 1 if resp is not None else False - except Exception: # noqa: BLE001 - return False +ORACLE_USER = "app" +ORACLE_PASSWORD = "super-secret" +ORACLE_SYSTEM_PASSWORD = "super-secret" + + +def _output_to_bytes(output: bytes | str | Iterator[bytes]) -> bytes: + if isinstance(output, bytes): + return output + if isinstance(output, str): + return output.encode() + return b"".join(output) + + +def _normalize_sqlplus_statement(sql: str) -> str: + statement = sql.strip() + if not statement.endswith(";"): + statement = f"{statement};" + return statement + + +def _exec_sqlplus( + container: Container, + user: str, + password: str, + service_name: str, + sql: str, +) -> tuple[int, bytes]: + script = "\n".join([ + "SET HEADING OFF FEEDBACK OFF PAGESIZE 0 VERIFY OFF ECHO OFF", + "WHENEVER OSERROR EXIT 9", + "WHENEVER SQLERROR EXIT SQL.SQLCODE", + _normalize_sqlplus_statement(sql), + "EXIT", + "", + ]) + connect_string = f"{user}/{password}@//localhost:1521/{service_name}" + command = f"printf '%s' {shlex.quote(script)} | sqlplus -L -S {shlex.quote(connect_string)}" + result = container.exec_run(["bash", "-lc", command]) + return result.exit_code if result.exit_code is not None else -1, _output_to_bytes(result.output) @dataclass @@ -47,26 +73,19 @@ def _provide_oracle_service( image: str, name: str, service_name: str, + user: str, + password: str, + system_password: str, ) -> Generator[OracleService, None, None]: - user = "app" - password = "super-secret" - system_password = "super-secret" - def check(_service: ServiceContainer) -> bool: - try: - conn = oracledb.connect( - host=_service.host, - port=_service.port, - user=user, - password=password, - service_name=service_name, - ) - with conn.cursor() as cursor: - cursor.execute("SELECT 1 FROM dual") - resp = cursor.fetchone() - return resp[0] == 1 if resp is not None else False - except Exception: # noqa: BLE001 - return False + exit_code, output = _exec_sqlplus( + _service.container, + user, + password, + service_name, + "SELECT 1 FROM dual", + ) + return exit_code == 0 and output.strip() == b"1" worker_num = get_xdist_worker_num() if worker_num is not None: @@ -115,14 +134,37 @@ def oracle_18c_service_name() -> str: return "xepdb1" +@pytest.fixture(autouse=False, scope="session") +def oracle_user() -> str: + return ORACLE_USER + + +@pytest.fixture(autouse=False, scope="session") +def oracle_password() -> str: + return ORACLE_PASSWORD + + +@pytest.fixture(autouse=False, scope="session") +def oracle_system_password() -> str: + return ORACLE_SYSTEM_PASSWORD + + @pytest.fixture(autouse=False, scope="session") def oracle_23ai_service( - docker_service: DockerService, oracle_23ai_image: str, oracle_23ai_service_name: str + docker_service: DockerService, + oracle_23ai_image: str, + oracle_23ai_service_name: str, + oracle_user: str, + oracle_password: str, + oracle_system_password: str, ) -> Generator[OracleService, None, None]: with _provide_oracle_service( image=oracle_23ai_image, name="oracle23ai", service_name=oracle_23ai_service_name, + user=oracle_user, + password=oracle_password, + system_password=oracle_system_password, docker_service=docker_service, ) as service: yield service @@ -130,12 +172,20 @@ def oracle_23ai_service( @pytest.fixture(autouse=False, scope="session") def oracle_18c_service( - docker_service: DockerService, oracle_18c_image: str, oracle_18c_service_name: str + docker_service: DockerService, + oracle_18c_image: str, + oracle_18c_service_name: str, + oracle_user: str, + oracle_password: str, + oracle_system_password: str, ) -> Generator[OracleService, None, None]: with _provide_oracle_service( image=oracle_18c_image, name="oracle18c", service_name=oracle_18c_service_name, + user=oracle_user, + password=oracle_password, + system_password=oracle_system_password, docker_service=docker_service, ) as service: yield service @@ -145,36 +195,3 @@ def oracle_18c_service( @pytest.fixture(autouse=False, scope="session") def oracle_service(oracle_23ai_service: OracleService) -> OracleService: return oracle_23ai_service - - -@pytest.fixture(autouse=False, scope="session") -def oracle_18c_connection( - oracle_18c_service: OracleService, -) -> Generator[oracledb.Connection, None, None]: - with oracledb.connect( - host=oracle_18c_service.host, - port=oracle_18c_service.port, - user=oracle_18c_service.user, - service_name=oracle_18c_service.service_name, - password=oracle_18c_service.password, - ) as db_connection: - yield db_connection - - -@pytest.fixture(autouse=False, scope="session") -def oracle_23ai_connection( - oracle_23ai_service: OracleService, -) -> Generator[oracledb.Connection, None, None]: - with oracledb.connect( - host=oracle_23ai_service.host, - port=oracle_23ai_service.port, - user=oracle_23ai_service.user, - service_name=oracle_23ai_service.service_name, - password=oracle_23ai_service.password, - ) as db_connection: - yield db_connection - - -@pytest.fixture(autouse=False, scope="session") -def oracle_startup_connection(oracle_23ai_startup_connection: oracledb.Connection) -> oracledb.Connection: - return oracle_23ai_startup_connection diff --git a/src/pytest_databases/docker/yugabyte.py b/src/pytest_databases/docker/yugabyte.py index e448ae0..93a6d8a 100644 --- a/src/pytest_databases/docker/yugabyte.py +++ b/src/pytest_databases/docker/yugabyte.py @@ -24,6 +24,7 @@ YUGABYTE_PASSWORD = "yugabyte" YUGABYTE_DB = "yugabyte" YUGABYTE_DATABASE = "pytest_databases" +YUGABYTE_TSERVER_FLAGS = "reject_writes_min_disk_space_mb=128" def _output_to_bytes(output: bytes | str | Iterator[bytes]) -> bytes: @@ -270,7 +271,7 @@ def yugabyte_responsive(_service: ServiceContainer) -> bool: container_port=5433, # YugabyteDB YSQL port check=yugabyte_responsive, name=container_name, - command="bin/yugabyted start --background=false", + command=f"bin/yugabyted start --background=false --tserver_flags={YUGABYTE_TSERVER_FLAGS}", transient=xdist_yugabyte_isolation_level == "server", timeout=120, pause=1.0, diff --git a/tests/test_oracle.py b/tests/test_oracle.py index 39c1334..0c1b0d8 100644 --- a/tests/test_oracle.py +++ b/tests/test_oracle.py @@ -3,6 +3,31 @@ import pytest +@pytest.fixture(scope="module") +def oracle_test_helpers() -> str: + return """ + import shlex + + def run_sqlplus(service, sql): + statement = sql.strip() + if not statement.endswith(";"): + statement = f"{statement};" + script = "\\n".join([ + "SET HEADING OFF FEEDBACK OFF PAGESIZE 0 VERIFY OFF ECHO OFF", + "WHENEVER OSERROR EXIT 9", + "WHENEVER SQLERROR EXIT SQL.SQLCODE", + statement, + "EXIT", + "", + ]) + connect_string = f"{service.user}/{service.password}@//localhost:1521/{service.service_name}" + command = f"printf '%s' {shlex.quote(script)} | sqlplus -L -S {shlex.quote(connect_string)}" + result = service.container.exec_run(["bash", "-lc", command]) + assert result.exit_code == 0, result.output.decode(errors="replace") + return [line.strip() for line in result.output.decode().splitlines() if line.strip()] + """ + + @pytest.mark.parametrize( "service_fixture", [ @@ -10,41 +35,16 @@ "oracle_23ai_service", ], ) -def test_service_fixture(pytester: pytest.Pytester, service_fixture: str) -> None: +def test_service_fixture(pytester: pytest.Pytester, service_fixture: str, oracle_test_helpers: str) -> None: pytester.makepyfile(f""" - import oracledb pytest_plugins = ["pytest_databases.docker.oracle"] - def test({service_fixture}): - conn = oracledb.connect( - user={service_fixture}.user, - password={service_fixture}.password, - service_name={service_fixture}.service_name, - host={service_fixture}.host, - port={service_fixture}.port, - ) - with conn.cursor() as cur: - cur.execute("SELECT 1 FROM dual") - res = cur.fetchone()[0] - assert res == 1 - """) - - result = pytester.runpytest_subprocess("-p", "pytest_databases") - result.assert_outcomes(passed=1) - - -@pytest.mark.parametrize("connection_fixture", ["oracle_18c_connection", "oracle_23ai_connection"]) -def test_connection_fixture(pytester: pytest.Pytester, connection_fixture: str) -> None: - pytester.makepyfile(f""" - import oracledb - pytest_plugins = ["pytest_databases.docker.oracle"] + {oracle_test_helpers} - def test({connection_fixture}): - with {connection_fixture}.cursor() as cursor: - cursor.execute("CREATE or replace view simple_table as SELECT 1 as the_value from dual") - cursor.execute("select * from simple_table") - result = cursor.fetchall() - assert bool(result is not None and result[0][0] == 1) + def test({service_fixture}): + assert run_sqlplus({service_fixture}, "SELECT 1 FROM dual") == ["1"] + run_sqlplus({service_fixture}, "CREATE or replace view simple_table as SELECT 1 as the_value from dual") + assert run_sqlplus({service_fixture}, "select * from simple_table") == ["1"] """) result = pytester.runpytest_subprocess("-p", "pytest_databases") diff --git a/uv.lock b/uv.lock index 7c7eeef..4b16f92 100644 --- a/uv.lock +++ b/uv.lock @@ -1345,7 +1345,7 @@ name = "exceptiongroup" version = "1.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/50/79/66800aadf48771f6b62f7eb014e352e5d06856655206165d775e675a02c9/exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219", size = 30371, upload-time = "2025-11-21T23:01:54.787Z" } wheels = [ @@ -2930,65 +2930,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/7a/7fe66f5f3682b1dd47d88cc4e11f1c6c0966b737de2d16671146e23c39a5/opentelemetry_semantic_conventions-0.63b1-py3-none-any.whl", hash = "sha256:dfe5ef4dee82586b746f522b818ceb298d00b3d59f660042bd79404bff8d0682", size = 203713, upload-time = "2026-05-21T16:32:47.016Z" }, ] -[[package]] -name = "oracledb" -version = "4.0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cryptography", version = "47.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version <= '3.9'" }, - { name = "cryptography", version = "48.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version > '3.9'" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f3/01/203599755aaff4f79683c2d61d2e6dc9d30f6228485d9e0280cc358cede3/oracledb-4.0.1.tar.gz", hash = "sha256:34bbea44423ed8b24093aa859ca7ee9b6e76ea490f9acdc5f6ff01aa1083e343", size = 879077, upload-time = "2026-05-19T18:14:34.881Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/4e/d1a16f398963eb41a6a1024030bf6c5ead34df2f9e558fbf24759effa703/oracledb-4.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:dbe8b44fea57385617838f2acfce8cc19f6c95cd9e65e7235e86b5932af1acd9", size = 4374567, upload-time = "2026-05-19T18:14:41.043Z" }, - { url = "https://files.pythonhosted.org/packages/db/da/849e06ddd29f5d8807ba9fb93ebdf210958273eeb12ca08f72d9f07f87cb/oracledb-4.0.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e3d54b624748cfe42248c4bc62c3f788632a2077058485a9acb3150312b1c396", size = 2499287, upload-time = "2026-05-19T18:14:43.321Z" }, - { url = "https://files.pythonhosted.org/packages/fe/b6/d6df13f297ccf64396867da84bed8529e2c1755839207746e5ac2cc6abc2/oracledb-4.0.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29ae0ff517a3241060eeee15a321b710c3f83a688cf2da7d5729adbe212e2b00", size = 2689995, upload-time = "2026-05-19T18:14:44.832Z" }, - { url = "https://files.pythonhosted.org/packages/01/98/5dec7011c2c26c8c3c2f9ea76783e2bc6cd6ad5f0489782f9cf4637e733f/oracledb-4.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:73ba32597fe1da72e0824aaa4b1900ec08a3b77268cb4eb45c733ae7e7043e70", size = 2540194, upload-time = "2026-05-19T18:14:46.615Z" }, - { url = "https://files.pythonhosted.org/packages/09/ef/21049e705a5dbac0011e647a4dcaf1746a501e8e19da98bd1674b21206d7/oracledb-4.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ce3f25552fe58df5c266874f8b13f0a8ab7fcd09ab4b476bc15520a67527ca4b", size = 2714751, upload-time = "2026-05-19T18:14:48.09Z" }, - { url = "https://files.pythonhosted.org/packages/4f/c1/0e02cc9f84b92a2fc8cbcb48be22b43076c511392b6ec36795e8a9ebc424/oracledb-4.0.1-cp310-cp310-win32.whl", hash = "sha256:7db5a43c29a23ed23923a29816c65c7a81fe00f2abfe6bf36d83ad952abd9b89", size = 1546877, upload-time = "2026-05-19T18:14:50.081Z" }, - { url = "https://files.pythonhosted.org/packages/b9/4a/d14ac7ed4e2f87f77807eaed88d8a2e787219407f170e80546cbebc466dd/oracledb-4.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:03afeda85bec3eca983ebf3ad9910d0f217d99300258366d287e015a041d6c13", size = 1894743, upload-time = "2026-05-19T18:14:52.038Z" }, - { url = "https://files.pythonhosted.org/packages/88/46/f38813e076a43cfa632db2b80761c0b1aa1c85dca7b89720d4984b3b2e17/oracledb-4.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:86a06d0afb3bb3a24bace0e72fb9abca2093efe0fa3457c65c13ba4eb5000b0b", size = 4351657, upload-time = "2026-05-19T18:14:53.834Z" }, - { url = "https://files.pythonhosted.org/packages/0f/e6/8ad2592ae4d5657882b900bad1b1286f1b29befa0f418df8550d8f7defd6/oracledb-4.0.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:416b324cd7715073cf5f3d577330387ffd59741463995c25bdc2d82b3e80b88e", size = 2492515, upload-time = "2026-05-19T18:14:55.834Z" }, - { url = "https://files.pythonhosted.org/packages/08/4e/eaab1183a2ba63e7f8673e3305f5382488c773d8f51d9a705e90d8b8b3e1/oracledb-4.0.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce6319ee01dcbb4d74f0e2a5794c6a566f339958ecac9830c67c7070521620e2", size = 2680701, upload-time = "2026-05-19T18:14:57.418Z" }, - { url = "https://files.pythonhosted.org/packages/44/f5/824b419dc3758c86ddcb1d8f69d1e7957882e58e99a3907a45a063ed0878/oracledb-4.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:873fcca53306e2b3b445a7d657cddc19e415a7aa7e392c473dfd1a3ae3970989", size = 2542151, upload-time = "2026-05-19T18:14:59.173Z" }, - { url = "https://files.pythonhosted.org/packages/be/5c/35b60bb1c85be5607913a24467052d6496eed9493793989de2a6b9b71147/oracledb-4.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b09eec35681d72c9476e6d715b89bb775724a31e7363df6beba7470494ea8040", size = 2709740, upload-time = "2026-05-19T18:15:01.03Z" }, - { url = "https://files.pythonhosted.org/packages/79/22/d4639df519c7cca02f45b3404c9e7934970f50a0296f704be7b1805b1ce7/oracledb-4.0.1-cp311-cp311-win32.whl", hash = "sha256:08e84a6af1b6e5921dba088dd9fc0738927206eafe5ce9763c34195f87556849", size = 1543018, upload-time = "2026-05-19T18:15:02.516Z" }, - { url = "https://files.pythonhosted.org/packages/20/88/7304ff7d512f45d6804501e404ceb7e567eb15661cd7d06c9ffaa6025cb5/oracledb-4.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:3b5ef1676a27b7e0a7ec55be27fd8f6d28d1601f5e8dfdae78705909f25b7c0a", size = 1901166, upload-time = "2026-05-19T18:15:04.096Z" }, - { url = "https://files.pythonhosted.org/packages/2d/b5/079fe8aa90cb769c68a54dde7591b374c64260d3d448c086acf4585cb8fc/oracledb-4.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:90586b3c7729b9cf3d40df902e81257f01e15e3408d8b6b9dbf91e939b64f72c", size = 1586727, upload-time = "2026-05-19T18:15:05.523Z" }, - { url = "https://files.pythonhosted.org/packages/53/1a/237ddaa33fe9576e1bb1ee9008eba2269fe49dee974a581465589eac658e/oracledb-4.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c05a01d6ad610a88c2aa1a43b1dc0a8485f5fbd4374d2b36908859d4205de192", size = 4345951, upload-time = "2026-05-19T18:15:07.482Z" }, - { url = "https://files.pythonhosted.org/packages/d8/bd/2ee10e0bd4d7a44db68a3f10d8941a5ea762bdb9dcff9b37739b2554e011/oracledb-4.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf61e42b9ef723dbdd0b23032b695e872009ed7341003df59d9a97cd960df977", size = 2290431, upload-time = "2026-05-19T18:15:09.041Z" }, - { url = "https://files.pythonhosted.org/packages/80/54/98fac98c9c1e2461512dcad81d2bd491fb7fe779d5044614867b2e827a78/oracledb-4.0.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c2d394453f669858bec942ff0da18b6ebade296ece823d582ad2b464ed5c6c90", size = 2493620, upload-time = "2026-05-19T18:15:10.635Z" }, - { url = "https://files.pythonhosted.org/packages/58/71/ebeade4753fd20b6d9cc7568c3853bec44425f24982def220835544008ca/oracledb-4.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d7cd278d59780e22e0a7451d208460756d779dc62b55bdbd95652f9640fbf8c3", size = 2329161, upload-time = "2026-05-19T18:15:12.158Z" }, - { url = "https://files.pythonhosted.org/packages/21/1d/4ec3ef256633126b669b99bf14e1c2af264ecb25c28f80f5365ea279c39a/oracledb-4.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b73820521eccd290506af94e1ffb9a8a5941b4018e3861df9b040652a7cef123", size = 2513518, upload-time = "2026-05-19T18:15:14.863Z" }, - { url = "https://files.pythonhosted.org/packages/7c/7a/4506477b52bb2db61a114202beab19bf24859f9fdc0979b8031042582477/oracledb-4.0.1-cp312-cp312-win32.whl", hash = "sha256:8fcad6d9628923281bf21e48a391ac2f87ec6950dc63381d8fea470e3128aef0", size = 1498632, upload-time = "2026-05-19T18:15:16.361Z" }, - { url = "https://files.pythonhosted.org/packages/dd/66/3d2246e5473b85c61d4b206ea9fcf50619db6b60a1425e34a3a1c1f64c44/oracledb-4.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:523b3356cde9d588ba250cefafdfc34869233d65c179f805ea6e4d3d6b209a7f", size = 1846730, upload-time = "2026-05-19T18:15:18.532Z" }, - { url = "https://files.pythonhosted.org/packages/dd/95/70420ebc1f051cff48cffb48f720540446d3fc497f7d9ba6f2e63337cb3f/oracledb-4.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:10204432f0eea8707a79c75bdccb84071e43fd19c658cb3b34d1746b12c6e7fe", size = 1518529, upload-time = "2026-05-19T18:15:19.916Z" }, - { url = "https://files.pythonhosted.org/packages/e3/52/c95031186ddec3788ee72708df406a6b7bafa308bd04722b7d5857942366/oracledb-4.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:443b2f03461e873ccd73dff3d8541fcf974c05e13e296a6687ffbb0c4a72c0a1", size = 4331008, upload-time = "2026-05-19T18:15:21.762Z" }, - { url = "https://files.pythonhosted.org/packages/ae/c3/7aaf12fe0f8b8323bce4647762722268da6b3b04ab1ff2349e4b43d30515/oracledb-4.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae894ca2705929eb0ac228329336fd03388ad6e3b54002be6f5d4400a8feaf52", size = 2284457, upload-time = "2026-05-19T18:15:23.727Z" }, - { url = "https://files.pythonhosted.org/packages/db/1e/48af5b2c559ee2fbee2ad13372858f34f2260cd9727b8ccad6cbe26e09b8/oracledb-4.0.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b42725337f80d433a3bd2928c08667e5b89da9ce05cf9ae3a4189c4fc4805ea", size = 2506136, upload-time = "2026-05-19T18:15:26.057Z" }, - { url = "https://files.pythonhosted.org/packages/1f/79/50cb8f7a3bc7ef9edc61db5fbf0ee2af9a4f487f4967eb54cc9f330ea908/oracledb-4.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8e13ff1e6f28fdb863180d23fa94cb42c619c29d2981e24992431e51b97caa54", size = 2332705, upload-time = "2026-05-19T18:15:27.632Z" }, - { url = "https://files.pythonhosted.org/packages/48/7d/6eea9e9ffece7d270a7d3caf364b5033fa8c73a0f377c10750eca8760a6e/oracledb-4.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e36581bb10e719d928dad12018c2d42606db2c34f49d6665b06f701f049255f0", size = 2528849, upload-time = "2026-05-19T18:15:29.437Z" }, - { url = "https://files.pythonhosted.org/packages/97/5c/553afdf90a144e25c5ee9825fbbc0c88d52bcf2b1dd7c5b509cad1022a60/oracledb-4.0.1-cp313-cp313-win32.whl", hash = "sha256:86ac65cbc8d29626b1d9d203f9151566c26a78e55bdfc030c06169ae8017f458", size = 1503094, upload-time = "2026-05-19T18:15:30.838Z" }, - { url = "https://files.pythonhosted.org/packages/b9/73/9305fa2755b234352e29dd5ed6063d017a661ccb08c06da5e14db90b143d/oracledb-4.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:a029dcee759bca56a8c95e952040c3d3f57e5ec05965355293b21930a66967fb", size = 1846068, upload-time = "2026-05-19T18:15:32.475Z" }, - { url = "https://files.pythonhosted.org/packages/fd/d8/6995a755dbdeee1eab1a6cb77283e3ab6634631512c47e2c3a64efcb515f/oracledb-4.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:20a10f903c8da59e9689a98bd68012f78fa19bed950ad9f19cd8f5b8b97e73a0", size = 1518345, upload-time = "2026-05-19T18:15:34.156Z" }, - { url = "https://files.pythonhosted.org/packages/e6/c1/e31ea17105b037b8b637a0e2936fc3cab65f87098c79df50fdf443a0ca6e/oracledb-4.0.1-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:cb7727f93ff962ab826bc3d0bca4b0e5bf45ecb7c525551c70c9e094f0f27027", size = 4374586, upload-time = "2026-05-19T18:15:36.73Z" }, - { url = "https://files.pythonhosted.org/packages/14/87/541fec6a6e37b74cd113007927e9caced188cf262f6015e88732651b7cc9/oracledb-4.0.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:032ca4f558b05f03fa1bef1b04e59ec350ae0b22e6d85c47f4ac62ae98315823", size = 2324417, upload-time = "2026-05-19T18:15:38.795Z" }, - { url = "https://files.pythonhosted.org/packages/c6/ba/14b9112c3f81c2b26cdd16748a5317263db1227e363bd29491d3291ad6e8/oracledb-4.0.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7156ef112a901967b3ee89b6c582bafc5a3082c47ca566de1a79e9ac3b48da32", size = 2528659, upload-time = "2026-05-19T18:15:40.38Z" }, - { url = "https://files.pythonhosted.org/packages/44/5a/cddfbdf30d23edd6484aa022f5e329eaecced2ead27cc2c01a05065d3e2d/oracledb-4.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:8159c5bd8f25b0ca0ce30f21e7a732a2bdfb4adb81b9c8ea1ca75339d8ec8398", size = 2374071, upload-time = "2026-05-19T18:15:42.069Z" }, - { url = "https://files.pythonhosted.org/packages/c7/c9/1561ab033f35bbccaca4f07360b6c446eb2726ab03754fbb5506e2d3fe89/oracledb-4.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e4926e699a42c526137724960fa4303ecb0b542186b11d3705ac84414a896508", size = 2552725, upload-time = "2026-05-19T18:15:43.541Z" }, - { url = "https://files.pythonhosted.org/packages/bd/22/a5dacf6d5d976850bf7c62b8c1ef7f1a56a56421962f081bc421ab8eb952/oracledb-4.0.1-cp314-cp314-win32.whl", hash = "sha256:b05bfadbfe462c39cc97258a973972f5bbbc9f8e2e9a4c2e0efcb1ec86b91088", size = 1525688, upload-time = "2026-05-19T18:15:44.944Z" }, - { url = "https://files.pythonhosted.org/packages/36/eb/1f959914455bda7e02531c5c07a5c6a2354ce164b29281f441777747a1b2/oracledb-4.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:0ece951553c106a0896c8e1690bcdf69d472761fa65fec9b8152cbce13ab8b81", size = 1890335, upload-time = "2026-05-19T18:15:46.7Z" }, - { url = "https://files.pythonhosted.org/packages/2f/b1/1289009c7407953fd19960dca73be921a4f6c88b097a6db59e0a2138bfc4/oracledb-4.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:0d3c6ed987df64b914ece0722692419fe494d07f15bb4d7715adeada4f914c3a", size = 1572519, upload-time = "2026-05-19T18:15:48.234Z" }, - { url = "https://files.pythonhosted.org/packages/46/be/dd8c0a18d496b11f565cced00bf4a0a20a7565ad056c677e53ca8bd26fd9/oracledb-4.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:828dd4c981b286f0467feab1c035fae8d3888cfdc707706841734821877ae1f3", size = 4379827, upload-time = "2026-05-19T18:15:50.099Z" }, - { url = "https://files.pythonhosted.org/packages/32/23/4751bbbf72498e5252a4d1d69f58d6f9e60c23725be2bca090ad5a8da205/oracledb-4.0.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7bbe5611f9196f0ec15d4bf838ec728d89586a962a20d65cad898aec020e11c4", size = 2504709, upload-time = "2026-05-19T18:15:51.694Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c0/9a73e030dacacce939c53ab330d563ebf83dc0645269e6796fcf28817ec1/oracledb-4.0.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f521b3f3f14fa9b8e748aeb79b064ae6767fcb0e8ff969a9aba7a852f059658", size = 2689699, upload-time = "2026-05-19T18:15:53.169Z" }, - { url = "https://files.pythonhosted.org/packages/9e/39/de4a5aa506401f762901c564372d0e332e3062c7dfe68e01fbaaf9307626/oracledb-4.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5332a4499d61c3cd659ed09bbd0d3c9a4c74a70bd51136d5c3de9127dc6d7434", size = 2544443, upload-time = "2026-05-19T18:15:54.644Z" }, - { url = "https://files.pythonhosted.org/packages/e5/de/91359ab8df8ccfc0feee33f2a1cc427c44d6110b7e7bd94c476d898320c0/oracledb-4.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c24b174aac8163065736072a726a50091791f6d30ac5c44965cf7044e86fbaf8", size = 2715791, upload-time = "2026-05-19T18:15:55.985Z" }, - { url = "https://files.pythonhosted.org/packages/4f/69/9c9308c4ab4263c1dd775f383a8076d08c113c45f8039ac8eee4e71a0f2c/oracledb-4.0.1-cp39-cp39-win32.whl", hash = "sha256:5646c126d4ab506ee2bda261e792f0036231ee929296057e79857ec678d86d4f", size = 1549265, upload-time = "2026-05-19T18:15:58.298Z" }, - { url = "https://files.pythonhosted.org/packages/6d/2a/5182cebd444d32b0a359c75dd28626f626b9edaf64b6f6718634dbd36d3e/oracledb-4.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:d132af7d95474d207632363575c7968b09e2d33dd24af3a36f539254433f4ae8", size = 1897410, upload-time = "2026-05-19T18:16:00.02Z" }, -] - [[package]] name = "packaging" version = "26.2" @@ -4012,9 +3953,6 @@ keydb = [ mongodb = [ { name = "pymongo" }, ] -oracle = [ - { name = "oracledb" }, -] postgres = [ { name = "psycopg", version = "3.2.13", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "psycopg", version = "3.3.4", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, @@ -4174,7 +4112,6 @@ requires-dist = [ { name = "filelock" }, { name = "google-cloud-bigquery", marker = "extra == 'bigquery'" }, { name = "google-cloud-spanner", marker = "extra == 'spanner'" }, - { name = "oracledb", marker = "extra == 'oracle'" }, { name = "psycopg", marker = "extra == 'cockroachdb'" }, { name = "psycopg", marker = "extra == 'postgres'", specifier = ">=3" }, { name = "pyarrow", marker = "extra == 'gizmosql'" },