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

如何使用pytest-qgis解决'Cannot find proj.db'错误及CRS无效问题?

QGIS测试中无法加载EPSG:4326,提示proj.db找不到

问题详情

编写了如下测试代码:

def test_trans():
    dst_crs = QgsCoordinateReferenceSystem("EPSG:4326")
    print(dst_crs)
    assert True

预期输出<QgsCoordinateReferenceSystem: EPSG:4326>,但实际返回<QgsCoordinateReferenceSystem: invalid>,同时抛出错误:

proj_create_from_database: Cannot find proj.db

需要解决该问题,且禁止手动设置环境变量,保证跨环境运行的灵活性。

重现步骤

  • 克隆pytest-qgis仓库:
    git clone git@github.com:GispoCoding/pytest-qgis.git
    
  • 进入仓库目录:
    cd pytest-qgis
    
  • 按照文档搭建开发环境:
    # 使用QGIS自带的Python创建虚拟环境
    /your/QGIS/python/path -m venv .venv --system-site-packages
    source .venv/bin/activate
    python -m pip install -U pip setuptools
    pip install pip-tools
    pip-sync requirements.txt requirements-dev.txt
    pre-commit install
    
  • 在tests目录下创建test_foo.py:
    from qgis.core import QgsCoordinateReferenceSystem
    
    def test_trans():
        dst_crs = QgsCoordinateReferenceSystem("EPSG:4326")
        print(dst_crs)
        assert True
    
  • 执行测试命令:
    pytest tests/test_foo.py -v -s
    

解决方案

方法1:使用pytest-qgis内置的qgis_app fixture

pytest-qgis提供的qgis_app fixture会自动完成QGIS的完整初始化流程,包括自动配置PROJ依赖路径,无需手动干预。修改测试代码引入该fixture即可:

from qgis.core import QgsCoordinateReferenceSystem

def test_trans(qgis_app):
    dst_crs = QgsCoordinateReferenceSystem("EPSG:4326")
    print(dst_crs)
    assert dst_crs.isValid()

运行测试时,pytest会自动触发qgis_app的初始化逻辑,它会处理所有QGIS运行所需的环境配置,包括定位proj.db文件。

方法2:代码内动态配置PROJ路径

如果不想依赖qgis_app fixture,可以通过QGIS API自动获取PROJ数据库路径,动态设置环境变量:

import os
from qgis.core import QgsCoordinateReferenceSystem, QgsApplication

def test_trans():
    # 初始化QGIS应用实例(未初始化时执行)
    if not QgsApplication.instance():
        QgsApplication.setPrefixPath("/your/QGIS/installation/path", True)
        qgs_app = QgsApplication([], False)
        qgs_app.initQgis()
    
    # 自动定位proj.db并设置PROJ_LIB环境变量
    proj_db_dir = os.path.join(QgsApplication.prefixPath(), "share", "proj")
    proj_db_path = os.path.join(proj_db_dir, "proj.db")
    if os.path.exists(proj_db_path):
        os.environ.setdefault("PROJ_LIB", proj_db_dir)
    
    dst_crs = QgsCoordinateReferenceSystem("EPSG:4326")
    print(dst_crs)
    assert dst_crs.isValid()

这种方式通过QGIS的prefixPath自动推导PROJ数据库的位置,动态设置PROJ_LIB,避免了手动配置环境变量的繁琐,适配不同的QGIS安装环境。

核心原因

问题本质是QGIS初始化过程中未正确配置PROJ库的路径,proj.db是PROJ用于查询坐标参考系统的核心数据库文件,必须让PROJ库能找到该文件才能正常创建CRS实例。上述两种方法均通过代码层面自动完成路径配置,保证跨环境的兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 11:05:19