-
Notifications
You must be signed in to change notification settings - Fork 49
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
DB access consistency #408
Changes from all commits
2a827d2
da24031
911d324
42b94d6
71cadb5
8c897bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ def get_shared_mongo_client(host, port, connect): | |
|
||
class PanMongo(object): | ||
|
||
def __init__(self, db='panoptes', host='localhost', port=27017, connect=False): | ||
def __init__(self, db='panoptes', host='localhost', port=27017, connect=False, logger=None): | ||
"""Connection to the running MongoDB instance | ||
|
||
This is a collection of parameters that are initialized when the unit | ||
|
@@ -49,11 +49,15 @@ def __init__(self, db='panoptes', host='localhost', port=27017, connect=False): | |
|
||
Args: | ||
db (str, optional): Name of the database containing the PANOPTES collections. | ||
host (str, optional): hostname running MongoDB | ||
port (int, optional): port running MongoDb | ||
connect (bool, optional): Connect to mongo on create, defaults to True | ||
host (str, optional): hostname running MongoDB. | ||
port (int, optional): port running MongoDb. | ||
connect (bool, optional): Connect to mongo on create, defaults to True. | ||
logger (None, optional): An instance of the logger. | ||
|
||
""" | ||
if logger is not None: | ||
self.logger = logger | ||
|
||
# Get the mongo client | ||
self._client = get_shared_mongo_client(host, port, connect) | ||
|
||
|
@@ -77,20 +81,28 @@ def __init__(self, db='panoptes', host='localhost', port=27017, connect=False): | |
# Add the collection as an attribute | ||
setattr(self, collection, getattr(db_handle, collection)) | ||
|
||
def _warn(self, *args, **kwargs): | ||
if hasattr(self, 'logger'): | ||
self.logger.warning(*args, **kwargs) | ||
else: | ||
warn(*args) | ||
|
||
def insert_current(self, collection, obj, include_collection=True): | ||
"""Insert an object into both the `current` collection and the collection provided | ||
"""Insert an object into both the `current` collection and the collection provided. | ||
|
||
Args: | ||
collection (str): Name of valid collection within panoptes db | ||
obj (dict or str): Object to be inserted | ||
collection (str): Name of valid collection within panoptes db. | ||
obj (dict or str): Object to be inserted. | ||
include_collection (bool): Whether to also update the collection, | ||
defaults to True | ||
defaults to True. | ||
|
||
Returns: | ||
str: Mongo object ID of record in `collection` | ||
str: Mongo object ID of record. If `include_collection` is True, will | ||
be the id of the object in the `collection`, otherwise will be the | ||
id of object in the `current` collection. | ||
""" | ||
if include_collection: | ||
assert collection in self.collections, warn("Collection not available") | ||
assert collection in self.collections, self._warn("Collection not available") | ||
|
||
_id = None | ||
try: | ||
|
@@ -101,16 +113,53 @@ def insert_current(self, collection, obj, include_collection=True): | |
} | ||
|
||
# Update `current` record | ||
self.current.replace_one({'type': collection}, current_obj, True) | ||
_id = self.current.replace_one( | ||
{'type': collection}, current_obj, True # True for upsert | ||
).upserted_id | ||
|
||
if include_collection: | ||
# Insert record into db | ||
col = getattr(self, collection) | ||
_id = col.insert_one(current_obj).inserted_id | ||
except AttributeError: | ||
warn("Collection does not exist in db: {}".format(collection)) | ||
_id = self.insert(collection, current_obj) | ||
except Exception as e: | ||
self._warn("Problem inserting object into collection: {}, {!r}".format(e, current_obj)) | ||
|
||
return _id | ||
|
||
def insert(self, collection, obj): | ||
"""Insert an object into the collection provided. | ||
|
||
The `obj` to be stored in a collection should include the `type` | ||
and `date` metadata as well as a `data` key that contains the actual | ||
object data. If these keys are not provided then `obj` will be wrapped | ||
in a corresponding object that does contain the metadata. | ||
|
||
Args: | ||
collection (str): Name of valid collection within panoptes db. | ||
obj (dict or str): Object to be inserted. | ||
|
||
Returns: | ||
str: Mongo object ID of record in `collection`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Error behavior? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There currently isn't any error that is raised as we just catch the exceptions and give a warning. Not sure if that is ideal or not but it does allow operations to continue. |
||
""" | ||
assert collection in self.collections, self._warn("Collection not available") | ||
|
||
_id = None | ||
try: | ||
# If `data` key is present we assume it has "metadata" (see above). | ||
if isinstance(obj, dict) and 'data' in obj: | ||
# But still check for a `type` | ||
if 'type' not in obj: | ||
obj['type'] = collection | ||
else: | ||
obj = { | ||
'type': collection, | ||
'data': obj, | ||
'date': current_time(datetime=True), | ||
} | ||
|
||
# Insert record into db | ||
col = getattr(self, collection) | ||
_id = col.insert_one(obj).inserted_id | ||
except Exception as e: | ||
warn("Problem inserting object into collection: {}".format(e)) | ||
self._warn("Problem inserting object into collection: {}, {!r}".format(e, obj)) | ||
|
||
return _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.
Nothing changed except the wrapping, right?
If so, why was this changed, as it was 100 chars wide, which I thought we'd agreed on.
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.
100 char limit means it wraps at 99, which this line is. From the pep8: