Skip to content

separate query log message args with a comma #110

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

Merged
merged 2 commits into from
Aug 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 5 additions & 33 deletions django_mongodb/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from django.core.exceptions import ImproperlyConfigured
from django.db.backends.utils import logger
from django.utils.version import get_version_tuple
from pymongo.cursor import Cursor


def check_django_compatability():
Expand Down Expand Up @@ -41,12 +40,11 @@ def profile_call(self, func, args=(), kwargs=None):
return duration, retval

def log(self, op, duration, args, kwargs=None):
# If kwargs are used by any operations in the future, they must be
# added to this logging.
Comment on lines 42 to +44
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the likelihood that any operations will be added here in the future?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. You can look at the kwargs for update_many(), for example, and see if you think developers will need some way to specify any of them for QuerySet operations.

msg = "(%.3f) %s"
args = " ".join(str(arg) for arg in args)
args = ", ".join(str(arg) for arg in args)
operation = f"{self.collection.name}.{op}({args})"
kwargs = {k: v for k, v in kwargs.items() if v}
if kwargs:
operation += f"; kwargs={kwargs}"
if len(settings.DATABASES) > 1:
msg += f"; alias={self.db.alias}"
self.db.queries_log.append(
Expand All @@ -62,19 +60,15 @@ def log(self, op, duration, args, kwargs=None):
extra={
"duration": duration,
"sql": operation,
"kwargs": kwargs,
"alias": self.db.alias,
},
)

def find(self, *args, **kwargs):
return DebugCursor(self, self.collection, *args, **kwargs)

def logging_wrapper(method):
def wrapper(self, *args, **kwargs):
func = getattr(self.collection, method)
# Collection.insert_one() mutates args[0] (the document) by adding
# the _id. deepcopy() to avoid logging that version.
# Collection.insert_many() mutates args (the documents) by adding
# _id. deepcopy() to avoid logging that version.
original_args = copy.deepcopy(args)
duration, retval = self.profile_call(func, args, kwargs)
self.log(method, duration, original_args, kwargs)
Expand All @@ -84,30 +78,8 @@ def wrapper(self, *args, **kwargs):

# These are the operations that this backend uses.
aggregate = logging_wrapper("aggregate")
count_documents = logging_wrapper("count_documents")
insert_many = logging_wrapper("insert_many")
delete_many = logging_wrapper("delete_many")
update_many = logging_wrapper("update_many")

del logging_wrapper


class DebugCursor(Cursor):
def __init__(self, collection_wrapper, *args, **kwargs):
self.collection_wrapper = collection_wrapper
super().__init__(*args, **kwargs)

def _refresh(self):
super_method = super()._refresh
if self._Cursor__id is not None:
return super_method()
# self.__id is None: first time the .find() iterator is
# entered. find() profiling happens here.
duration, retval = self.collection_wrapper.profile_call(super_method)
kwargs = {
"limit": self._Cursor__limit,
"skip": self._Cursor__skip,
"sort": self._Cursor__ordering,
}
self.collection_wrapper.log("find", duration, [self._Cursor__spec], kwargs)
return retval