-
-
Notifications
You must be signed in to change notification settings - Fork 310
Fix MySQL native ENUM autogenerate detection #1746
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
base: main
Are you sure you want to change the base?
Fix MySQL native ENUM autogenerate detection #1746
Conversation
zzzeek
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.
hi and thanks for this.
Here are the changes I'd like to see:
- add "Fixes: #779" to the commit message and remove #1745 which is a dupe
- remove all the unnecessary isinstance/conditionals from the compare_type implementation
- replace the entire test suite here with a single suite in test_mysql.py that is adapted from https://github.com/sqlalchemy/alembic/blob/dcba64415a3ef898078f04890712add7a8d18789/tests/test_autogen_diffs.py#L728C5-L770C1
thanks!
|
Thank you for the detailed feedback! I've addressed all the review comments: Changes Made:1. Simplified
|
|
ok thanks for the changes |
|
What a coincidence… I ran into this same issue on Friday as well. |
Test Import Bug Fixed 🔧I identified and fixed a critical test infrastructure bug that was causing the failing checks: IssueThe test file had incorrect decorator usage:
Fix Applied
VerificationAll local checks now pass:
The test pattern now correctly matches the established convention used in CI checks should now pass. Ready for 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.
Pull request overview
This PR fixes a critical bug in Alembic's autogenerate functionality where changes to MySQL native ENUM column values (additions, removals, or reorderings) were not being detected. The fix overrides the compare_type() method in the MySQLImpl class to perform explicit comparison of ENUM values rather than relying on the base implementation's string tokenization approach.
Key Changes
- Added
compare_type()method override inMySQLImplto handle MySQL native ENUM comparison - Created comprehensive test suite with 6 test scenarios covering ENUM value changes
- Added necessary imports to test file for ENUM types
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| alembic/ddl/mysql.py | Implements compare_type() override to detect ENUM value differences by comparing the enums attribute directly |
| tests/test_mysql.py | Adds MySQLEnumCompareTest class with fixture-based parameterized tests covering various ENUM comparison scenarios and necessary imports |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
alembic/ddl/mysql.py
Outdated
| if isinstance(metadata_type, sqltypes.Enum) and isinstance( | ||
| inspector_type, sqltypes.Enum | ||
| ): | ||
| # Compare the actual enum values |
Copilot
AI
Dec 3, 2025
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.
Add a comment explaining that order matters for MySQL ENUM comparison since the PR description emphasizes this. This helps future maintainers understand the importance:
# Compare the actual enum values (order matters for MySQL ENUMs)
if metadata_type.enums != inspector_type.enums:
return True| # Compare the actual enum values | |
| # Compare the actual enum values; order matters for MySQL ENUMs. | |
| # Changing the order of ENUM values is a schema change in MySQL. |
|
@zzzeek can you check again, when you have time. I think it's okay for merging. |
sqla-tester
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.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 0155dbc of this pull request into gerrit so we can run tests and reviews and stuff
|
New Gerrit review created for change 0155dbc: https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/6520 |
|
i have a lot going on at the moment will try to get to this |
0155dbc to
94fbc24
Compare
|
@zzzeek Fixed the CI failure. There were two issues:
Both are now fixed. CI should pass on this push. |
This commit addresses a critical bug where Alembic's autogenerate feature fails to detect when values are added to, removed from, or reordered in MySQL native ENUM columns. Changes: - Override compare_type() in MySQLImpl to properly compare ENUM values - Add comprehensive test suite for ENUM value changes (addition, removal, reordering) - Import MySQL ENUM type for proper type checking The bug was caused by the base implementation only comparing ENUM type names but not the actual enum values. This resulted in silent schema mismatches where migrations would run successfully but fail to update the database schema, leading to runtime errors when the application attempted to use new ENUM values. Fixes: sqlalchemy#1745 Test coverage: - test_enum_value_added: Verifies detection of new ENUM values - test_enum_value_removed: Verifies detection of removed ENUM values - test_enum_value_reordered: Verifies detection of reordered ENUM values - test_enum_no_change: Ensures identical ENUMs are not flagged - test_mysql_enum_dialect_type: Tests MySQL-specific ENUM type
Per reviewer feedback, simplified the compare_type() method and restructured tests to follow existing patterns. Changes: - Removed unnecessary MySQL_ENUM import from alembic/ddl/mysql.py - Simplified compare_type() method (removed redundant isinstance, hasattr checks, and elif blocks for MySQL_ENUM) - Since MySQL_ENUM is already a subclass of sqltypes.Enum, we only need to check for sqltypes.Enum - Moved tests from separate test_mysql_enum.py into test_mysql.py - Restructured tests to follow the @Combinations pattern from test_autogen_diffs.py (lines 728-770) - Removed setUp/tearDown in favor of @Combinations.fixture() Fixes: sqlalchemy#779
- Added missing 'from alembic import testing' import - Fixed decorator usage: @testing.fixture() and @testing.combinations() (was incorrectly using @Combinations.fixture() and @Combinations()) - Applied Black formatting (line wrapping for readability) - All syntax, import, and formatting checks now pass This resolves the AttributeError that was causing test failures.
94fbc24 to
5031ce9
Compare
|
Hey @zzzeek 👋 Sorry for the long silence - my GitHub account got suspended for about 2 months due to a misunderstanding, so this PR went stale. I'm back now and just rebased on latest main. All your previous review comments were addressed in my last push before the suspension. Let me know if there's anything else needed! Happy to make changes. Thanks for your patience 🙏 |
sqla-tester
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.
OK, this is sqla-tester setting up my work on behalf of zzzeek to try to get revision 5031ce9 of this pull request into gerrit so we can run tests and reviews and stuff
|
Patchset 5031ce9 added to existing Gerrit review https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/6520 |
|
hey there, oh, "misunderstandings", too bad :) anyway, a lot has happened in alembic in the past two will see how this goes |
|
Michael Bayer (zzzeek) wrote: recheck View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/6520 |
haha yeah, "misunderstandings" is one way to put it. github support had a different opinion apparently. anyway, good to be back - let me know if anything needs to change here |
sqla-tester
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.
Federico Caselli (CaselIT) wrote:
looks fine, left a couple of suggestions
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/6520
| inspector_type, sqltypes.Enum | ||
| ): | ||
| # Compare the actual enum values | ||
| if metadata_type.enums != inspector_type.enums: |
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.
Federico Caselli (CaselIT) wrote:
could we use set here? I don't think the order matters
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/6520
tests/test_mysql.py
Outdated
| def test_compare_enum_types( | ||
| self, inspected_type, metadata_type, expected, connection | ||
| ): | ||
| from alembic.ddl.mysql import MySQLImpl |
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.
Federico Caselli (CaselIT) wrote:
we could move this at module level
View this in Gerrit at https://gerrit.sqlalchemy.org/c/sqlalchemy/alembic/+/6520
|
Updated PR based on review:
Thanks for the feedback! |
Description
This PR fixes a critical bug where Alembic's
--autogeneratefeature fails to detect when values are added to, removed from, or reordered in MySQL native ENUM columns.Problem
Currently, when you modify a MySQL native ENUM column in your model:
Running
alembic revision --autogenerateeither:This causes silent schema mismatches leading to runtime errors when the application tries to use the new ENUM value.
Solution
This PR overrides the
compare_type()method inMySQLImplto:sqlalchemy.types.Enumandmysql.ENUM)Changes
Core Fix (
alembic/ddl/mysql.py):compare_type()method toMySQLImplclassMySQL_ENUMfor proper type detectionTest Suite (
tests/test_mysql_enum.py):@combinations(("backend",))for actual database testingImport Updates (
tests/test_mysql.py):Checklist
This pull request is:
Fixes: #1745Code Quality
All checks passing:
Impact
Testing
To test locally:
Related
Closes #1745
Thank you for reviewing! This fix addresses a production-critical issue that has affected many Alembic users with MySQL native ENUMs.