Django 1.11升级至2.2后执行makemigrations报AttributeError的替代解决方案咨询
Hey there, let's work through this issue you're facing after upgrading from Django 1.11 to 2.2. That AttributeError is a common gotcha with specific versions of Django 2.2, and we've got solid solutions that work even in Docker environments.
Why This Happens
Looking at your error trace, the problem stems from this line in django/db/backends/mysql/operations.py:
query = query.decode(errors='replace')
In Python 3, strings are already Unicode by default—calling .decode() on a str object doesn't make sense. Django fixed this bug in version 2.2.20 and above, which is why you don't see it in newer 2.2 releases or older versions.
Solutions That Work in Docker
Here are your best options, ordered by maintainability:
1. Upgrade Django to the Latest 2.2 LTS Patch Release
This is the cleanest, most sustainable fix. Since Django 2.2 is a long-term support (LTS) version, it gets regular security and bug-fix updates. Upgrading to the latest 2.2.x release (like 2.2.28, the final 2.2 release) will patch this issue without any manual code changes.
- Update your
requirements.txt(or dependency file of choice) to specify:Django>=2.2.20,<2.3 - In your Dockerfile, ensure you're installing dependencies from this updated file—no manual edits needed, and the fix will persist across every container build.
2. Patch the Django Code Automatically in Docker (If You Can't Upgrade)
If upgrading Django isn't feasible right now, you can bake a patch into your Docker build process so the fix is applied automatically every time:
- Create a patch file (name it
django-mysql-decode-fix.patch) with this content:
(Adjust line numbers if they don't match your exact Django 2.2 version.)diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index 9f8c4d6..a1b2c3d 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -143,7 +143,8 @@ class DatabaseOperations(BaseDatabaseOperations): query = super().last_executed_query(cursor, sql, params) # MySQLdb returns bytes if query is not None and isinstance(query, bytes): query = query.decode(errors='replace') +# Skip decode if query is already a string return query - Add this line to your Dockerfile right after installing dependencies:
This will apply the fix during every build, so you won't have to worry about manual changes being overwritten.RUN patch /usr/local/lib/python3.7/site-packages/django/db/backends/mysql/operations.py < django-mysql-decode-fix.patch
3. Check Compatibility of Dependencies Like ddtrace
Your error trace shows you're using ddtrace (Datadog's tracing library). While the main issue is Django's code, make sure you're using a ddtrace version compatible with Django 2.2. Upgrading to a recent release (e.g., >=0.40.0) can help avoid additional compatibility quirks that might compound this issue.
Final Notes
Sticking with the first option (upgrading Django to 2.2.20+) is always recommended—it includes other critical security fixes and patches, not just this one. It's the most low-maintenance solution for both local development and Docker deployments.
内容的提问来源于stack exchange,提问作者John

