-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Couchbase Collection Datanode and Add Unit Tests #2010
base: develop
Are you sure you want to change the base?
Conversation
- Added to handle data interactions with Couchbase collections. - Introduced for unit testing the functionality of the Couchbase Collection Datanode. - Ensured the implementation aligns with existing data node standards and includes necessary validation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's promising. Good starting point. I believe the overall idea is correct.
Now we need to go into the real implementation. There are some missing points. For example:
- what kind of documents are accepted? Do we need to define a Python object to structure the document?
- We are missing the _write, _append, and filter methods implementations
- For testing, we should have a Mock class acting like a CouchBase server without having to instantiate a real server
- etc...
def _read(self): | ||
"""Read all documents from the Couchbase collection.""" | ||
try: | ||
return [doc.content_as[dict] for doc in documents] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is documents here?
return [doc.content_as[dict] for doc in documents] | ||
except Exception as e: | ||
print(f"An error occurred: {e}") | ||
return [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO: We have to handle this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the review and the detailed feedback! I appreciate the direction, and I'm eager to work on the improvements.
-> For document structure, I will define a Python class or object to structure the documents, ensuring consistency in what
is accepted.
-> I will proceed with implementing the _write, _append, and filter methods. I understand these are essential for CRUD
operations.
-> For testing, I will create a Mock class to simulate Couchbase interactions, allowing us to test without needing an
actual Couchbase server.
…lass for testing, and updated documentation.
…lass for testing, updated documentation, and included all required features.
aa9dc40
to
7e1b8ca
Compare
Hey @jrobinAV Resolved outstanding issues in couchbase_collection_datanode.py:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @snehaamujri, thank you for your contribution.
I have some questions about the implementation.
properties.get(self.__DB_USERNAME_KEY, ""), | ||
properties.get(self.__DB_PASSWORD_KEY, "") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm quite sure that Couchbase requires username and password to connect.
If the properties
doesn't contain the username
and password
, we should raise an error before this, meaning that we should add the self.__DB_USERNAME_KEY
and self.__DB_PASSWORD_KEY
to the self._REQUIRED_PROPERTIES
) | ||
) | ||
) | ||
bucket = self.cluster.bucket(properties.get(self.__DB_NAME_KEY)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bucket = self.cluster.bucket(properties.get(self.__DB_NAME_KEY)) | |
bucket = self.cluster.bucket(properties.get(self.__BUCKET_KEY)) |
The constant should be renamed to match what it actually presents
try: | ||
if isinstance(data, dict): | ||
self.collection.upsert(data['id'],data) | ||
elif isinstance(data, list): | ||
for item in data: | ||
self.collection.upsert(item['id'], item) | ||
except CouchbaseException as e: | ||
print(f"An error occurred while writing:{e}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try: | |
if isinstance(data, dict): | |
self.collection.upsert(data['id'],data) | |
elif isinstance(data, list): | |
for item in data: | |
self.collection.upsert(item['id'], item) | |
except CouchbaseException as e: | |
print(f"An error occurred while writing:{e}") | |
try: | |
if isinstance(data, dict): | |
self.collection.upsert(data['id'],data) | |
elif isinstance(data, list): | |
for item in data: | |
self.collection.upsert(item['id'], item) | |
except CouchbaseException as e: | |
print(f"An error occurred while writing:{e}") |
The except
is misalign
class CouchbaseDocument: | ||
"""Class to define the structure of documents stored in Couchbase.""" | ||
|
||
def __init__(self, field1: str, field2: int, **kwargs): | ||
self.field1 = field1 # Example field of type string | ||
self.field2 = field2 # Example field of type integer | ||
# Additional fields can be added dynamically | ||
for key, value in kwargs.items(): | ||
setattr(self, key, value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this class being used?
What is it used for?
self.collection.upsert(data['id'],data) | ||
elif isinstance(data, list): | ||
for item in data: | ||
self.collection.upsert(item['id'], item) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the motivation for using upsert
here?
What should happens if the document doesn't have an id
?
from couchbase_collection_datanode import CouchBaseCollectionDataNode # Make sure this import is correct | ||
|
||
|
||
class TestCouchBaseCollectionDataNode(unittest.TestCase): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a test_read
to this class?
class MockCouchbaseCollection: | ||
def __init__(self): | ||
self.documents = {} | ||
|
||
def insert(self, doc_id, document): | ||
if doc_id in self.documents: | ||
raise Exception(f"Document with ID {doc_id} already exists.") | ||
self.documents[doc_id] = document | ||
|
||
def upsert(self, doc_id, document): | ||
self.documents[doc_id] = document | ||
|
||
def get(self, doc_id): | ||
if doc_id not in self.documents: | ||
raise Exception(f"Document with ID {doc_id} not found.") | ||
return self.documents[doc_id] | ||
|
||
def remove(self, doc_id): | ||
if doc_id not in self.documents: | ||
raise Exception(f"Document with ID {doc_id} not found.") | ||
del self.documents[doc_id] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As my understanding, the MockCouchbaseCollection is essentially a dictionary right?
def test_append_document(self): | ||
doc_id = "doc2" | ||
document = {"name": "Jane", "hobbies": []} | ||
self.data_node._write(doc_id, document) # Assuming _write is implemented correctly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work?
I'm asking because the signature of the CouchBaseCollectionDataNode._write()
method only requires 1 argument.
Here you are providing 2.
self.data_node._write(doc_id, document) # Assuming _write is implemented correctly | ||
|
||
additional_data = ["reading", "hiking"] | ||
self.data_node._append(doc_id, additional_data) # Assuming _append is implemented correctly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, does _append()
with 2 arguments work here?
@snehaamujri Your first version is promising but not completed yet. Have you had a chance to see our reviews? Do you have any questions? |
Hey @jrobinAV, |
This PR has been labelled as "🥶Waiting for contributor" because it has been inactive for more than 14 days. If you would like to continue working on this PR, then please add new commit or another comment, otherwise this PR will be closed in 14 days. For more information please refer to the contributing guidelines. |
@snehaamujri |
Issue #1862