Django迁移时如何指定新增列位置?无需删除数据库
调整Django迁移中数据库列的顺序(无需删除数据库)
当然可以搞定!Django默认确实会把新字段追加到表的最后一列,但我们有几种不用删库的办法来实现你的需求,具体要看你使用的数据库类型:
针对MySQL(最直接的方案)
MySQL支持在添加字段时指定位置,你可以通过修改自动生成的迁移文件来实现:
- 先在
models.py里把is_person字段放到paid_by后面,保存文件。 - 生成初始迁移文件:
python manage.py makemigrations - 找到你app下
migrations文件夹里刚生成的迁移文件(比如000x_add_is_person.py),打开它找到AddField操作,给它加上after参数:operations = [ migrations.AddField( model_name='person', name='is_person', field=models.CharField(blank=True, max_length=50, null=True), after='paid_by', # 关键:指定该字段放到paid_by之后 ), ] - 执行迁移:
这时候去数据库里查看,python manage.py migrateis_person就会出现在paid_by字段的后面了。
针对PostgreSQL
其实PostgreSQL本身不关心物理列顺序——不管字段在表里的物理位置如何,Django查询时都会按照你models.py里的顺序返回字段,所以大多数场景下不需要调整物理顺序。
如果非要调整物理位置(比如某些特定工具依赖列的物理顺序),可以通过自定义RunSQL操作执行PostgreSQL的特定语句:
- 生成一个空迁移:
python manage.py makemigrations --empty your_app_name - 在空迁移文件里添加
RunSQL操作:
注意这里的位置号从1开始计算,operations = [ migrations.RunSQL( "ALTER TABLE your_app_person ALTER COLUMN is_person SET POSITION 3;", # 回滚语句:把字段放回原来的位置(比如最后一列),你可以根据实际情况调整位置号 reverse_sql="ALTER TABLE your_app_person ALTER COLUMN is_person SET POSITION 8;" ) ]covid_id是1,paid_by是2,所以我们把is_person设为3。
针对SQLite
SQLite的限制较多,它不支持直接在指定位置添加字段。如果是开发环境用SQLite,你可以:
- 接受字段在最后(毕竟开发环境影响不大);
- 或者用第三方库比如
django-sqlite3-optimizer扩展Django的SQLite支持,实现列顺序调整; - 最坏情况,手动写
RunSQL操作:创建新表、复制旧表数据、删除旧表、重命名新表——但这个操作繁琐,不推荐在生产环境使用SQLite。
注意事项
- 如果已经执行过迁移(也就是
is_person已经在数据库最后一列了),不要修改之前的迁移文件,而是生成新的迁移来调整顺序(比如上面PostgreSQL和SQLite提到的RunSQL方式); - 生产环境操作前一定要备份数据库,避免意外;
- 如果你在团队协作,要确保所有人同步修改后的迁移文件,避免迁移不一致。
内容的提问来源于stack exchange,提问作者BootCamp
相关产品推荐
相关产品推荐

