变更后模型不同步主因是手动改库未同步ORM:Django需用makemigrations检测models.py与迁移文件差异,SQLAlchemy依赖alembic autogenerate扫描已导入模型。
变更后模型不同步:Django/SQLAlchemy 里 makemigrations 没跑或没生效
改了数据库表结构但 orm 模型没更新,最常见原因是只手动执行了 sql,忘了同步代码层。django 的 makemigrations 不会自动探测已存在的 ddl 变更,它只看 models.py 和已有 migration 文件的差异。
实操建议:
- 先确认当前迁移状态:
python manage.py showmigrations,看是否有未应用的 migration(标记为[ ]) - 如果改的是生产库且已有数据,别直接
makemigrations --empty手写迁移 —— 容易漏掉RunPython数据迁移逻辑 - Django 中字段重命名必须显式用
db_column+db_table配合AlterField或RenameField,否则生成的迁移会删列再建列,丢数据 - SQLAlchemy 用户注意:
alembic revision --autogenerate依赖target_metadata指向的模型,若模块没被 import,新增模型根本不会进 diff
跨环境同步失败:dev/staging/prod 的 migration 哈希不一致
本地 makemigrations 后 push 到 CI,结果 staging 报错 Migration … is not applied,本质是 migration 文件内容微小差异(比如空行、注释顺序)导致哈希值不同,Alembic/Django 都靠这个校验一致性。
实操建议:
- 所有 migration 文件必须提交进 Git,禁止在某台机器上
makemigrations后只传 .py 不传 .pyc 或忽略 __pycache__ - 团队统一编辑器设置:关闭保存时自动删除末尾空格、禁用格式化 migration 文件(尤其 Django 的
0001_initial.py) - Alembic 下避免手改
revision_id字段;Django 下别碰dependencies数组里的元组顺序 - 上线前用
python manage.py migrate --plan看实际要跑哪些步骤,比光看文件名更可靠
模块化管理卡点:多个 Django app 共享一张表,migrate 时提示冲突
当 app_a.models.UserProfile 和 app_b.models.UserProfile 都映射到同一张 user_profile 表,Django 默认会为每个 app 生成独立 migration,apply 时因表已存在报 Relation "user_profile" already exists。
采用 php+mysql 数据库方式运行的强大网上商店系统,执行效率高速度快,支持多语言,模板和代码分离,轻松创建属于自己的个性化用户界面 v3.5更新: 1).进一步静态化了活动商品. 2).提供了一些重要UFT-8转换文件 3).修复了除了网银在线支付其它支付显示错误的问题. 4).修改了LOGO广告管理,增加LOGO链接后主页LOGO路径错误的问题 5).修改了公告无法发布的问题,可能是打压
实操建议:
- 只允许一个 app 拥有该表的“所有权”——即定义
Meta.db_table = 'user_profile'并负责makemigrations,其余 app 用managed = False声明只读模型 - 若必须多处可写,改用
django.db.migrations.SeparateDatabaseAndState,把建表逻辑抽到单独 migration,其余迁移只操作 state - SQLAlchemy 的
metadata.create_all()不检查表是否存在,容易重复建表出错;应配合inspect(engine).has_table()做前置判断
大表加索引阻塞线上:ALTER TABLE 被锁死,migrate 卡住半小时
Django/Alembic 默认执行的 AddIndex 在 MySQL/PostgreSQL 上对千万级表会全表扫描并加写锁,期间所有写请求超时。这不是 ORM 问题,是数据库 DDL 本身的限制。
实操建议:
- MySQL 5.6+ 用
ALGORITHM=INPLACE, LOCK=NONE,但需在 migration 中显式指定:RunSQL("CREATE INDEX CONCURRENTLY ...", reverse_sql=...) - PostgreSQL 用
CONCURRENTLY,但注意它不能在事务块里运行,Django migration 默认包在事务中,得用atomic = False关闭 - 永远不要在高峰期跑含
AlterField(改类型)、AddConstraint的迁移 —— 这些几乎都不可并发,提前在低峰期用 pt-online-schema-change 或 gh-ost 替换
复杂点在于:数据库层的“在线变更”和 ORM 层的“迁移抽象”天然错位。你写的 AlterField 在 Django 看是原子操作,在 PostgreSQL 看可能是三步(新建列、拷数据、删旧列),中间任何一步失败都会让模型和 DB 状态不一致。这时候日志里不会报错,但应用读写会静默出错。









