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
Refs #29641 -- Refactored database schema constraint creation code. #10406
Conversation
5a75355
to
493c93e
Compare
493c93e
to
1b8916f
Compare
I pushed a few edits, including removing the unused attributes like Also, here's a failure if sqparse isn't installed:
Since installing sqlparse should be easy, I'm thinking it might be easier to raise an error for this case rather than to keep the old implementation that returns a made up name. What do you think? On Oracle:
|
1b8916f
to
c8331b1
Compare
I think I've resolved the failing test that looked for I am also in favour of requiring sqlparse for introspection on sqlite. What do you think is the best way to raise an error? The simplest would be to just allow the |
As for the Oracle failure, I'm not sure why the explicitly set constraint name isn't being used (or read by |
It seems to be in there but it's upper cased |
@Ian-Foote you probably want to rename django/django/db/backends/oracle/introspection.py Lines 93 to 95 in b9cf764
|
For sqlparse, you could use a technique similar to: django/django/db/backends/base/operations.py Lines 301 to 310 in c99d379
unless get_constraints() is called often enough the basically every project that uses SQLite will require it. In that case, it might be better to include a message in sqlite3/base.py similar to the error for requiring psycopg2 and mysqlclient.
|
c8331b1
to
58a8d2c
Compare
I've updated again. |
Some tests need to be skipped on sqlite if sqlparse isn't installed or else we need to make sqlparse a mandatory dependency when running the tests with sqlite (I think we'd add a message in |
@timgraham I see you've merged some of my related PRs. Are you planning to handle them all, or would you like me to take another look at any of them? I had been planning to get back to this, but I'm happy for you to take over if you prefer. |
e8ef716
to
aef4500
Compare
What do you think we should do about the previous point I raised? If we go with the first option, I think it's going to be difficult to identify which tests in new patches need to be skipped. The second option adds some friction for new contributors (but only if they skip |
I think the second option sounds preferable. |
Then I think we need to write to django-developers about making sqlparse a mandatory dependency for SQLite users and how that'll work exactly (i.e. should |
Are we talking about |
I think the question is what percentage of SQLite projects are going to end up needing sqlparse based on their migrations? If it's high enough, it might make for a better user experience to have users install it when they're getting started instead of a lazy error when I'll push a commit that shows how many migrations tests are affected -- but most of them aren't failing until the cleanup phase of the test (i.e. migrate to zero, which deletes indexes, etc.) |
aef4500
to
b1086ff
Compare
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.
FWIW I'd be in favour of shipping this PR without adding an hard dependency on sqlparse
.
The fact get_constraints
is only used in tests since the normal migrate
path must perform a full table rebuild on constraint addition and removal makes it unlikely for this path to be reached unless table introspection is used.
In all cases the ImproperlyConfigured
exception clearly states which adjustments are required just like our other soft dependencies such as PIL
.
That works for me. |
I see your point, although it looks like Are you in favor of making sqlparse a mandatory dependency for running the tests with SQLite? If so, should we add a helpful message in |
Ah right, I forgot we merged
I think that would make sense! |
Hi, new Check and Unique constraints look very useful, thx for that. However I wanna to left a few comments about extensibility of current schema. I wrote backend for postgres that apply a few tricks to avoid table
I'll be very appreciate if this points will be accepted. |
b1086ff
to
baedfdf
Compare
Simon, sure, I think the less sqlparse is required, the easier it'll be for users. Do you or Ian want to work on that? Paveł, I don't think this PR is the right place to bring up your points. Can you create a ticket at http://code.djangoproject.com/ and offer a patch? |
@timgraham I can work on it. Does a PR off this branch sounds good to you? We could reorder the commits here after. |
Yes |
} | ||
|
||
statement = sqlparse.parse(table_schema)[0] | ||
for token in statement.flatten(): |
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.
@Ian-Foote I discovered an issue with this approach is that it will include inlined named foreign key and primary key constraints as well.
https://www.sqlite.org/syntaxdiagrams.html#table-constraint
Django doesn't create such constraint itself but usually the introspection module is supposed to be able to deal with any form of schema. I'll include the adjustments in a following commit. Thanks for the parsing logic by the way, this is really neat.
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.
Thanks for the spot. I had help with the parsing logic from @MarkusH.
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.
Simon, did you fix this issue in your branch? Feel free to push an update here.
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.
Cool I'll do that later tonight.
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.
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.
Thanks. There might be a bug because when I rebase #10337, self.assertIn('unique_name', constraints)
fails on SQLite.
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 know what's causing it. Let me rebase #10337 on top of this branch. That's where the token.match(Token.Keyword, 'UNIQUE')
should live anyway.
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 did the rebase already, shall I push it to Ian's branch?
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.
yeah please do, that'll save me doing the rebase.
_constraint = True | ||
elif token.match(Token.Keyword, 'CHECK'): | ||
_check = True | ||
elif token.match(Token.Keyword, 'UNIQUE'): |
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.
Given SQLite also creates an index for unique constraints will be returned twice?
ba8710a
to
24dce86
Compare
There are a few failing
but |
I think removing those lines from the tests is fine. An alternative would be to override |
@timgraham @Ian-Foote I'm OK with removing those lines from tests 👍 . In other introspection methods on Oracle we are using lowercase names, so it will be consistent. |
Pushed a commit to fix the tests. To be squashed or else all |
I'm happy with squashing this. |
592921e
to
e5f9047
Compare
After trying to separate out the |
I don't remember |
@timgraham Agreed 👍. I think we can completely remove |
e5f9047
to
74f3363
Compare
Added a test for constraint names in the database. Updated SQLite introspection to use sqlparse to allow reading the constraint name for table check and unique constraints. Co-authored-by: Ian Foote <python@ian.feete.org>
74f3363
to
dba4a63
Compare
Add a test to ensure we set the constraint name correctly in the
database.
Update sqlite introspection to use sqlparse. This allows us to read the
actual constraint name for table check constraints and unique constraints.