-
Notifications
You must be signed in to change notification settings - Fork 30
INTPYTHON-743 Allow using MongoDB connection string in DATABASES["HOST"] #383
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
Conversation
59efa04 to
50d854b
Compare
8aca9ed to
ab88385
Compare
963cd39 to
836603e
Compare
aclark4life
left a comment
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.
LGTM, let's see if @ShaneHarvey has any feedback
ShaneHarvey
left a comment
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.
LGTM
| db_settings["OPTIONS"].update({"tls": True, "tlsAllowInvalidCertificates": True}) | ||
| uri = parse_uri(mongodb_uri) | ||
| if uri.get("username") and uri.get("password"): | ||
| db_settings["OPTIONS"] = {"tls": True, "tlsAllowInvalidCertificates": True} |
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 you add a comment here to explain what we are working around? It sounds like this could come out at some point based on @ShaneHarvey 's comment
I think one of the old concerns here was mixing of ssl and tls args. That should no longer be a problem if all drivers have dropped support for ssl=true.
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.
Also maybe of note we're only using PyMongo's parse_uri to get the username and password if they are in the URI.
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 thought the linked issue described the issue well, so I don't see a need to repeat it. As far as I understand, the workaround won't be necessary after that issue is closed.
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.
It's still confusing to use PyMongo's parse_uri to get the username and password in the context of deprecating our parse_uri because we can't rely on PyMongo's parse_uri when the query string arguments aren't regular characters e.g. I think PyMongo is doing something like this:
>>> URI = "mongodb://example.com/search?time=10:30"
>>> uri = parse_uri(URI)
>>> uri.get("hour")
10
>>> uri.get("minute")
30
Given that we've spent a lot of time getting to the status quo with parse_uri I want to make sure we're not adding more confusion in merging this feature.
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.
parse_uri is only used for MongoDB connection strings, it has nothing to do with http://.
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.
This logic is copied from:
django-mongodb-backend/django_mongodb_backend/utils.py
Lines 59 to 60 in d7f8fd2
| "USER": uri.get("username"), | |
| "PASSWORD": uri.get("password"), |
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.
parse_uri is only used for MongoDB connection strings, it has nothing to do with http://.
I fixed the example but the scheme doesn't matter, whether it's mongodb://, https:// or alex:// the MongoDB URI spec was inspired by but does not conform to the URI spec. To make things even more confusing, we add in dj-database-url's stated purpose of "12 factor app support" and my stated purpose of django_mongodb_backend.parse_uri is like dj-database-url.
E.g.
| Feature | RFC 3986 | MongoDB URI Difference | 12‑Factor |
|---|---|---|---|
| One host in authority | Yes | Multiple hosts with commas | Ensure your tooling/stack supports multi-host URIs when setting environment variables. |
| Reserved char encoding | Must percent-encode | Allowed unescaped in some drivers | Always URL-encode usernames and passwords to avoid parsing errors in env var consumers. |
| Query param case sensitivity | Case-sensitive | Case-insensitive | Use consistent lower-case keys in env vars for portability across drivers. |
| Semantics of query component | Opaque to RFC | MongoDB-specific options | Document driver-specific options and keep them minimal in environment variables. |
| Scheme semantics | Generic | mongodb / mongodb+srv with DNS expansion |
Ensure DNS queries are allowed and resolvable in the target runtime environment. |
</nit>
That said, we obviously only need to support the MongoDB URI and I think we are well on our way here with HOST.
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.
It's still confusing to use PyMongo's parse_uri to get the username and password in the context of deprecating our parse_uri
Are you still confused? I'm confused about what you're confused about. This is the same parsing as before, but without the intermediate call to django_mongodb_backend.parse_uri().
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.
Why are we calling PyMongo's parse_uri? Is there a scenario in which we don't have to do that and can that scenario happen now before we merge this.
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.
To check if the URI contains a username and password (and therefore, this is an ssl connection). Jib authored this workaround. I can try to find another workaround or try to solve the issue in mongo-orchestration (I'm unsure if there is still a blocker there), but I don't see why this should hold up this PR.
docs/source/releases/5.2.x.rst
Outdated
| ------------ | ||
|
|
||
| - Allowed specifying the MongoDB connection string in ``DATABASES["HOST"]``, | ||
| eliminating the need to use :func:`~django_mongodb_backend.utils.parse_uri` |
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.
Until we are sure, I'd probably refrain from declaring that we've eliminated the need for parse_uri. For example, can this be described as implementing a similar feature set as dj-database-url and if so, is this approach something that could eliminate the need for that 3rd party library in Django (via some upstream changes to Django) ?
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 think it's useful to inform users about the reason for the change so that they can try to migrate and let us know if there are any problems.
This is somewhat orthogonal to dj-database-url because it relies on the fact that MongoDB accepts a connection string as the host. Other database connectors like psycopg and mysqlclient don't necessarily work the same way.
There has been some discussion of trying to integrate of dj-database-url into Django. I don't think any work is imminent.
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.
This is somewhat orthogonal to dj-database-url
Yes it is but parse_uri is not (orthogonal to dj-database-url). So this does not eliminate the need for parse_uri.
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 not sure what you mean. Are you suggesting not to deprecate parse_uri? What use case for parse_uri do you have in mind?
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 think it's useful to inform users about the reason for the change so that they can try to migrate and let us know if there are any problems.
It's useful to inform them of the change but as someone who knows the reason for the change I can't say it's a particularly compelling or easy reason to tell and I don't think we'll gain any clarity on that in the short term. I would much rather see something like:
Hey you can just add the URI to the
HOSTand still setNAMEnow! (parse_uriis deprecated).
Dont' declare parse_uri eliminated because it implements a slightly different use case which has not been addressed with this change.
So just to clarify once more: we cannot support the database name in the URI because we are not parsing the URI?
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.
After more consideration, it seems feasible to support using the connection string's "defaultauthdb" as the database so that NAME isn't required. It's consistent with the fact that MongoClient.get_database() returns that db. The name does need to be parsed out because Django relies on settings_dict["NAME"] in django/db/backends/base/creation.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.
I think it should be good to go. I left this part as a separate commit to ease review.
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 think it should be good to go. I left this part as a separate commit to ease review.
I'm not sure what you mean. If we don't support /dbname in the URI in this PR then this PR does not "eliminate the need for parse_uri" because parse_uri still supports that. If we add support for /dbname in the URI in this PR, then this PR does indeed eliminate the need for parse_uri, for all practical purposes as far as I can tell.
The middle ground is to merge this and not say anything about parse_uri except maybe that it's deprecated.
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.
Support for /dbname is added in commit "parse db name out of connection string".
2484ae4 to
155c639
Compare
aclark4life
left a comment
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.
LEBTM (even better), thanks!
155c639 to
862c2cd
Compare
No description provided.