You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行migrate命令时出现djongo.exceptions.SQLDecodeError的解决方法

解决SimpleJWT黑名单与Djongo/MongoDB的迁移错误

问题详情

我开发的Django REST应用采用SimpleJWT做认证,按照官方文档添加rest_framework_simplejwt.token_blacklist到INSTALLED_APPS后,执行py manage.py migrate时触发djongo.exceptions.SQLDecodeError错误。使用MongoDB作为数据库,将该app从INSTALLED_APPS移除后,migrate命令可正常执行。

错误栈

Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, main, sessions, token_blacklist
Running migrations:
  Applying token_blacklist.0008_migrate_to_bigautofield...Not implemented alter command for SQL ALTER TABLE "token_blacklist_blacklistedtoken" ALTER COLUMN "id" TYPE long
Traceback (most recent call last):
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\cursor.py", line 51, in execute
    self.result = Query(
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 784, in __init__
    self._query = self.parse()
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 876, in parse
    raise e
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 857, in parse
    return handler(self, statement)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 889, in _alter
    query = AlterQuery(self.db, self.connection_properties, sm, self._params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 425, in __init__
    super().__init__(*args)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 84, in __init__
    super().__init__(*args)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 62, in __init__
    self.parse()
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 441, in parse
    self._alter(statement)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\sql2mongo\query.py", line 500, in _alter
    raise SQLDecodeError(f'Unknown token: {tok}')
djongo.exceptions.SQLDecodeError:

        Keyword: Unknown token: TYPE
        Sub SQL: None
        FAILED SQL: ('ALTER TABLE "token_blacklist_blacklistedtoken" ALTER COLUMN "id" TYPE long',)
        Params: ([],)
        Version: 1.3.6

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\cursor.py", line 59, in execute
    raise db_exe from e
djongo.database.DatabaseError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    main()
  File "manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\management\__init__.py", line 425, in execute_from_command_line
    utility.execute()
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\management\__init__.py", line 419, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\management\base.py", line 373, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\management\base.py", line 417, in execute
    output = self.handle(*args, **options)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\management\base.py", line 90, in wrapped
    res = handle_func(*args, **kwargs)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\core\management\commands\migrate.py", line 253, in handle
    post_migrate_state = executor.migrate(
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\migrations\executor.py", line 126, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\migrations\executor.py", line 156, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\migrations\executor.py", line 236, in apply_migration
    state = migration.apply(state, schema_editor)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\migrations\migration.py", line 125, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\migrations\operations\fields.py", line 225, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\base\schema.py", line 620, in alter_field
    self._alter_field(model, old_field, new_field, old_type, new_type,
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\base\schema.py", line 777, in _alter_field
    self.execute(
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\base\schema.py", line 153, in execute
    cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 99, in execute
    return super().execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 67, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 76, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\MR.Robot\.virtualenvs\fsm-GjGxZg3c\lib\site-packages\djongo\cursor.py", line 59, in execute
    raise db_exe from e
django.db.utils.DatabaseError

INSTALLED_APPS配置

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework_simplejwt.token_blacklist',
    'drf_yasg',
    'main',
    'accounts',
]

依赖版本

anyio==3.5.0
asgiref==3.5.0
backports.zoneinfo==0.2.1
certifi==2021.10.8
charset-normalizer==2.0.12
coreapi==2.3.3
coreschema==0.0.4
Django==4.0.2
djangorestframework==3.13.1
djangorestframework-simplejwt==5.0.0
djongo==1.3.6
drf-yasg==1.20.0
idna==3.3
inflection==0.5.1
itypes==1.2.0
Jinja2==3.0.3
MarkupSafe==2.0.1
packaging==21.3
PyJWT==2.3.0
pymongo==3.12.1
pyparsing==3.0.7
pytz==2021.3
requests==2.27.1
ruamel.yaml==0.17.21
ruamel.yaml.clib==0.2.6
sniffio==1.2.0
sqlparse==0.2.4
tk==0.1.0
tzdata==2022.1
uritemplate==4.1.1
urllib3==1.26.8

解决方案

1. 伪造目标迁移(最快解决)

Djongo无法解析修改字段类型的SQL语句,而MongoDB本身不需要这种关系型数据库的字段类型变更操作,直接伪造执行黑名单app的0008_migrate_to_bigautofield迁移:

py manage.py migrate token_blacklist --fake 0008_migrate_to_bigautofield

之后再执行正常迁移:

py manage.py migrate

2. 降级SimpleJWT版本

SimpleJWT 5.0.0引入了这个针对关系型数据库的BigAutoField迁移,降级到4.x版本可绕过该问题:

pip install djangorestframework-simplejwt==4.8.0

3. 自定义黑名单模型(进阶)

若需要保留最新版SimpleJWT,可自定义黑名单模型继承官方抽象类,避开官方迁移:

  1. 在自己的app中创建模型:
    from rest_framework_simplejwt.token_blacklist.models import AbstractBlacklistedToken, AbstractOutstandingToken
    from django.db import models
    
    class BlacklistedToken(AbstractBlacklistedToken):
        id = models.ObjectIdField(primary_key=True)
    
    class OutstandingToken(AbstractOutstandingToken):
        id = models.ObjectIdField(primary_key=True)
    
  2. 在settings.py中配置:
    SIMPLE_JWT = {
        # 其他原有配置
        'BLACKLIST_AFTER_ROTATION': True,
        'BLACKLIST_MODEL': 'your_app.BlacklistedToken',
        'OUTSTANDING_TOKEN_MODEL': 'your_app.OutstandingToken',
    }
    
  3. 移除INSTALLED_APPS中的rest_framework_simplejwt.token_blacklist,执行自己app的迁移即可。

原因说明

错误源于Djongo无法解析SimpleJWT黑名单迁移中的ALTER TABLE ... ALTER COLUMN ... TYPE SQL语句——MongoDB是文档型数据库,不需要这种关系型数据库的字段类型变更操作,而SimpleJWT的该迁移是针对PostgreSQL、MySQL等关系型数据库设计的,因此与Djongo产生兼容性冲突。

内容的提问来源于stack exchange,提问作者Random User

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 21:15:37