Skip to content

Commit

Permalink
full cross-namespace management in DDL (#227)
Browse files Browse the repository at this point in the history
cross-namespace works for Database/Collection created in any way, and for all drop_collection calls
  • Loading branch information
hemidactylus authored Feb 29, 2024
1 parent 8001f3f commit 7ec1a7e
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 52 deletions.
8 changes: 8 additions & 0 deletions astrapy/idiomatic/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def __init__(
caller_version=caller_version,
)

@property
def namespace(self) -> str:
return self._astra_db_collection.astra_db.namespace

def __repr__(self) -> str:
return f'{self.__class__.__name__}[_astra_db_collection="{self._astra_db_collection}"]'

Expand Down Expand Up @@ -297,6 +301,10 @@ def __init__(
caller_version=caller_version,
)

@property
def namespace(self) -> str:
return self._astra_db_collection.astra_db.namespace

def __repr__(self) -> str:
return f'{self.__class__.__name__}[_astra_db_collection="{self._astra_db_collection}"]'

Expand Down
12 changes: 6 additions & 6 deletions astrapy/idiomatic/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ def drop_collection(self, name_or_collection: Union[str, Collection]) -> None:
# lazy importing here against circular-import error
from astrapy.idiomatic.collection import Collection

_name: str
if isinstance(name_or_collection, Collection):
_namespace = name_or_collection.namespace
_name = name_or_collection._astra_db_collection.collection_name
self._astra_db.copy(namespace=_namespace).delete_collection(_name)
else:
_name = name_or_collection
self._astra_db.delete_collection(_name)
self._astra_db.delete_collection(name_or_collection)

def list_collection_names(
self,
Expand Down Expand Up @@ -355,12 +355,12 @@ async def drop_collection(
# lazy importing here against circular-import error
from astrapy.idiomatic.collection import AsyncCollection

_name: str
if isinstance(name_or_collection, AsyncCollection):
_namespace = name_or_collection.namespace
_name = name_or_collection._astra_db_collection.collection_name
await self._astra_db.copy(namespace=_namespace).delete_collection(_name)
else:
_name = name_or_collection
await self._astra_db.delete_collection(_name)
await self._astra_db.delete_collection(name_or_collection)

async def list_collection_names(
self,
Expand Down
45 changes: 44 additions & 1 deletion tests/idiomatic/integration/test_ddl_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

import pytest

from ..conftest import ASTRA_DB_SECONDARY_KEYSPACE, TEST_COLLECTION_NAME
from ..conftest import (
AstraDBCredentials,
ASTRA_DB_SECONDARY_KEYSPACE,
TEST_COLLECTION_NAME,
)
from astrapy import AsyncCollection, AsyncDatabase


Expand Down Expand Up @@ -66,3 +70,42 @@ async def test_database_list_collections_cross_namespace_async(
assert TEST_COLLECTION_NAME not in await async_database.list_collection_names(
namespace=ASTRA_DB_SECONDARY_KEYSPACE
)

@pytest.mark.skipif(
ASTRA_DB_SECONDARY_KEYSPACE is None, reason="No secondary keyspace provided"
)
@pytest.mark.describe("test of cross-namespace collection lifecycle, async")
async def test_collection_namespace_async(
self,
async_database: AsyncDatabase,
astra_db_credentials_kwargs: AstraDBCredentials,
) -> None:
TEST_LOCAL_COLLECTION_NAME1 = "test_crossns_coll1"
TEST_LOCAL_COLLECTION_NAME2 = "test_crossns_coll2"
database_on_secondary = AsyncDatabase(
astra_db_credentials_kwargs["api_endpoint"],
astra_db_credentials_kwargs["token"],
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
await async_database.create_collection(
TEST_LOCAL_COLLECTION_NAME1,
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
col2_on_secondary = await async_database.create_collection(
TEST_LOCAL_COLLECTION_NAME2,
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert (
TEST_LOCAL_COLLECTION_NAME1
in await database_on_secondary.list_collection_names()
)
await database_on_secondary.drop_collection(TEST_LOCAL_COLLECTION_NAME1)
await async_database.drop_collection(col2_on_secondary)
assert (
TEST_LOCAL_COLLECTION_NAME1
not in await database_on_secondary.list_collection_names()
)
assert (
TEST_LOCAL_COLLECTION_NAME2
not in await database_on_secondary.list_collection_names()
)
44 changes: 43 additions & 1 deletion tests/idiomatic/integration/test_ddl_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

import pytest

from ..conftest import ASTRA_DB_SECONDARY_KEYSPACE, TEST_COLLECTION_NAME
from ..conftest import (
AstraDBCredentials,
ASTRA_DB_SECONDARY_KEYSPACE,
TEST_COLLECTION_NAME,
)
from astrapy import Collection, Database


Expand Down Expand Up @@ -64,3 +68,41 @@ def test_database_list_collections_cross_namespace_sync(
assert TEST_COLLECTION_NAME not in sync_database.list_collection_names(
namespace=ASTRA_DB_SECONDARY_KEYSPACE
)

@pytest.mark.skipif(
ASTRA_DB_SECONDARY_KEYSPACE is None, reason="No secondary keyspace provided"
)
@pytest.mark.describe("test of cross-namespace collection lifecycle, sync")
def test_collection_namespace_sync(
self,
sync_database: Database,
astra_db_credentials_kwargs: AstraDBCredentials,
) -> None:
TEST_LOCAL_COLLECTION_NAME1 = "test_crossns_coll1"
TEST_LOCAL_COLLECTION_NAME2 = "test_crossns_coll2"
database_on_secondary = Database(
astra_db_credentials_kwargs["api_endpoint"],
astra_db_credentials_kwargs["token"],
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
sync_database.create_collection(
TEST_LOCAL_COLLECTION_NAME1,
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
col2_on_secondary = sync_database.create_collection(
TEST_LOCAL_COLLECTION_NAME2,
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert (
TEST_LOCAL_COLLECTION_NAME1 in database_on_secondary.list_collection_names()
)
database_on_secondary.drop_collection(TEST_LOCAL_COLLECTION_NAME1)
sync_database.drop_collection(col2_on_secondary)
assert (
TEST_LOCAL_COLLECTION_NAME1
not in database_on_secondary.list_collection_names()
)
assert (
TEST_LOCAL_COLLECTION_NAME2
not in database_on_secondary.list_collection_names()
)
21 changes: 0 additions & 21 deletions tests/idiomatic/unit/test_collections.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import pytest

from ..conftest import ASTRA_DB_SECONDARY_KEYSPACE
from astrapy import AsyncCollection, AsyncDatabase


Expand Down Expand Up @@ -137,3 +138,30 @@ async def test_collection_conversions_caller_mutableness_async(
)
assert col1.copy() == col2
assert col1.to_sync().to_async() == col2

@pytest.mark.skipif(
ASTRA_DB_SECONDARY_KEYSPACE is None, reason="No secondary keyspace provided"
)
@pytest.mark.describe("test collection namespace property, async")
async def test_collection_namespace_async(
self,
async_database: AsyncDatabase,
) -> None:
col1 = await async_database.get_collection("id_test_collection")
assert col1.namespace == async_database.namespace

col2 = await async_database.get_collection(
"id_test_collection",
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert col2.namespace == ASTRA_DB_SECONDARY_KEYSPACE

col3 = AsyncCollection(async_database, "id_test_collection")
assert col3.namespace == async_database.namespace

col4 = AsyncCollection(
async_database,
"id_test_collection",
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert col4.namespace == ASTRA_DB_SECONDARY_KEYSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import pytest

from ..conftest import ASTRA_DB_SECONDARY_KEYSPACE
from astrapy import Collection, Database


Expand Down Expand Up @@ -137,3 +138,30 @@ def test_collection_conversions_caller_mutableness_sync(
)
assert col1.copy() == col2
assert col1.to_async().to_sync() == col2

@pytest.mark.skipif(
ASTRA_DB_SECONDARY_KEYSPACE is None, reason="No secondary keyspace provided"
)
@pytest.mark.describe("test collection namespace property, sync")
def test_collection_namespace_sync(
self,
sync_database: Database,
) -> None:
col1 = sync_database.get_collection("id_test_collection")
assert col1.namespace == sync_database.namespace

col2 = sync_database.get_collection(
"id_test_collection",
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert col2.namespace == ASTRA_DB_SECONDARY_KEYSPACE

col3 = Collection(sync_database, "id_test_collection")
assert col3.namespace == sync_database.namespace

col4 = Collection(
sync_database,
"id_test_collection",
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert col4.namespace == ASTRA_DB_SECONDARY_KEYSPACE
21 changes: 0 additions & 21 deletions tests/idiomatic/unit/test_databases.py

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@

import pytest

from ..conftest import AstraDBCredentials, TEST_COLLECTION_INSTANCE_NAME
from ..conftest import (
AstraDBCredentials,
ASTRA_DB_SECONDARY_KEYSPACE,
TEST_COLLECTION_INSTANCE_NAME,
)
from astrapy.defaults import DEFAULT_KEYSPACE_NAME
from astrapy import AsyncCollection, AsyncDatabase


Expand Down Expand Up @@ -125,3 +130,23 @@ async def test_database_conversions_caller_mutableness_async(
)
assert db1.to_sync().to_async() == db2
assert db1.copy() == db2

@pytest.mark.skipif(
ASTRA_DB_SECONDARY_KEYSPACE is None, reason="No secondary keyspace provided"
)
@pytest.mark.describe("test database namespace property, async")
async def test_database_namespace_async(
self,
astra_db_credentials_kwargs: AstraDBCredentials,
) -> None:
db1 = AsyncDatabase(
**astra_db_credentials_kwargs,
)
assert db1.namespace == DEFAULT_KEYSPACE_NAME

db2 = AsyncDatabase(
token=astra_db_credentials_kwargs["token"],
api_endpoint=astra_db_credentials_kwargs["api_endpoint"],
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert db2.namespace == ASTRA_DB_SECONDARY_KEYSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@

import pytest

from ..conftest import AstraDBCredentials, TEST_COLLECTION_INSTANCE_NAME
from ..conftest import (
AstraDBCredentials,
ASTRA_DB_SECONDARY_KEYSPACE,
TEST_COLLECTION_INSTANCE_NAME,
)
from astrapy.defaults import DEFAULT_KEYSPACE_NAME
from astrapy import Collection, Database


Expand Down Expand Up @@ -126,3 +131,23 @@ def test_database_conversions_caller_mutableness_sync(
)
assert db1.to_async().to_sync() == db2
assert db1.copy() == db2

@pytest.mark.skipif(
ASTRA_DB_SECONDARY_KEYSPACE is None, reason="No secondary keyspace provided"
)
@pytest.mark.describe("test database namespace property, sync")
def test_database_namespace_sync(
self,
astra_db_credentials_kwargs: AstraDBCredentials,
) -> None:
db1 = Database(
**astra_db_credentials_kwargs,
)
assert db1.namespace == DEFAULT_KEYSPACE_NAME

db2 = Database(
token=astra_db_credentials_kwargs["token"],
api_endpoint=astra_db_credentials_kwargs["api_endpoint"],
namespace=ASTRA_DB_SECONDARY_KEYSPACE,
)
assert db2.namespace == ASTRA_DB_SECONDARY_KEYSPACE

0 comments on commit 7ec1a7e

Please sign in to comment.