在Windows上使用shp2pgsql.exe将Shapefile导入PostgreSQL/PostGIS数据库的Python脚本

5 投票
1 回答
6040 浏览
提问于 2025-04-17 22:13

我有一个PostgreSQL数据库,托管在Windows 2008 Server RT虚拟机上(我知道应该放在Linux虚拟机上,但这是我们组织的要求。唉……)

我们的地理信息系统(GIS)团队会把很多形状文件放到一个仓库里。我们想要一个自动处理的程序,定期检查这个文件夹。我们希望把这些文件添加到我们的Postgres地理数据库中,以便进行一些我们正在开发的其他处理。

我想要处理大量的形状文件,把它们的几何信息和文件名加载到我们的数据库里。

这是我目前已经实现的导入功能的核心部分:

import os, subprocess
base_dir = r"c:\shape_file_repository"
full_dir = os.walk(base_dir)
shapefile_list = []
for source, dirs, files in full_dir:
    for file_ in files:
        if file_[-3:] == 'shp':
            #print "Found Shapefile"
            shapefile_path = base_dir + '/' + file_
            shapefile_list.append(shapefile_path)
for paths in shapefile_list:  
    #This is the part where I keep running into trouble. os.system also didnt work
    temp_bat = open(r"c:\temp\temp_shp.bat", "w")
    temp_bat.write(r'start /D c:\Program Files (x86)\PostgreSQL\8.4\bin\shp2pgsql.exe' + \
                   paths + "new_shp_table | psql -d geometry_database")
    temp_bat.close()
    subprocess.Popen(r"c:\temp\temp_shp.bat")

一旦几何信息被加载到新的数据库表中,我已经设置了代码,可以从临时表中提取几何信息,并把这些信息和形状文件的名称一起加载到我们的主数据库表中。我的问题是,我可以通过命令提示符来完成这个操作,但通过Python运行Windows命令或者把命令输出到批处理文件再运行似乎都不行。

1 个回答

4

这里有一些修改建议,可以让事情正常运作。不过,如果你想要在任何命令失败时收到通知,还需要进一步的修改。要注意的是,如果有多个shapefile的话,这个程序会出错,因为在你添加其他逻辑来移动或重命名那个表之前,new_shp_table这个表已经存在了,或者你需要用一个独特的名字来加载它。

另外,PostgreSQL 8.4将在今年晚些时候停止支持,所以你可能需要考虑在为时已晚之前,升级到更新的版本。

import os, subprocess

# Choose your PostgreSQL version here
os.environ['PATH'] += r';C:\Program Files (x86)\PostgreSQL\8.4\bin'
# http://www.postgresql.org/docs/current/static/libpq-envars.html
os.environ['PGHOST'] = 'localhost'
os.environ['PGPORT'] = '5432'
os.environ['PGUSER'] = 'someuser'
os.environ['PGPASSWORD'] = 'clever password'
os.environ['PGDATABASE'] = 'geometry_database'

base_dir = r"c:\shape_file_repository"
full_dir = os.walk(base_dir)
shapefile_list = []
for source, dirs, files in full_dir:
    for file_ in files:
        if file_[-3:] == 'shp':
            shapefile_path = os.path.join(base_dir, file_)
            shapefile_list.append(shapefile_path)
for shape_path in shapefile_list:
    cmds = 'shp2pgsql "' + shape_path + '" new_shp_table | psql '
    subprocess.call(cmds, shell=True)

撰写回答