Django 3.2升级至4.2后Spatialite单元测试报no such column: rowid错误
解决Django 4.2 + Spatialite 5测试时的rowid触发器错误
问题场景
将应用从Django 3.2升级至4.2,生产环境用PostGIS,单元测试使用django.contrib.gis.db.backends.spatialite作为数据库后端,运行测试时触发以下错误:
django.db.utils.OperationalError: error in trigger ISO_metadata_reference_row_id_value_insert: no such column: rowid
make: *** [django.mk:49: test] Error 1
这是Django 4.2与Spatialite 5的已知兼容问题,执行./manage.py shell -c "import django;django.db.connection.cursor().execute('SELECT InitSpatialMetaData(1);')"临时方案无效。
环境配置:
- Django 4.2.11
- sqlite 3.42.0
- libspatialite 5.0.1
- Python 3.12.2
- Fedora Linux
可行解决方案
1. 升级Django至修复版本
该兼容问题已在Django 4.2.12及更高的4.2系列补丁版本,以及5.0.6及以上版本中修复。直接升级Django即可解决:
pip install django>=4.2.12
2. 手动修改Spatialite触发器(临时修复)
如果暂时无法升级Django,可手动修改出错的触发器,将触发器中引用的rowid替换为ISO_metadata_reference表的主键字段(通常为id):
- 进入Django shell连接测试数据库:
./manage.py shell
- 执行SQL命令修改触发器:
from django.db import connection with connection.cursor() as cursor: # 删除原有错误触发器 cursor.execute("DROP TRIGGER IF EXISTS ISO_metadata_reference_row_id_value_insert;") # 创建新触发器,用主键id替代rowid cursor.execute(""" CREATE TRIGGER ISO_metadata_reference_row_id_value_insert AFTER INSERT ON ISO_metadata_reference FOR EACH ROW BEGIN UPDATE ISO_metadata_reference SET row_id_value = NEW.id WHERE id = NEW.id; END; """)
3. 降级libspatialite至4.x版本
由于问题源于Django 4.2与Spatialite 5的兼容问题,降级libspatialite到4.x系列版本(如4.3.0)也可规避该错误。在Fedora上可通过包管理器降级:
sudo dnf downgrade libspatialite-4.3.0
内容的提问来源于stack exchange,提问作者nnyby
相关产品推荐
相关产品推荐

