我加載一個shape文件到使用shp2pgsql一個PostGIS的數據庫,通過PSQL管道,包裹在一個python子是這樣的:無法shp2pgsql導入後設置psycopg2自動提交
command = "shp2pgsql -s 4269 -a -D -W LATIN1 file.shp table | psql -h host -d db -U user"
p=subprocess.Popen(command, shell=True)
p.communicate()
這工作完全,與下面的輸出:
Loading objects...
Shapefile type: Polygon
Postgis type: MULTIPOLYGON[2]
SET
SET
BEGIN
COMMIT
沒有END
聲明,但據我所知END
和COMMIT
是等價的。
然後我想設置con.autocommit = True
psycopg2連接到同一個數據庫。我收到以下錯誤:
psycopg2.ProgrammingError: autocommit cannot be used inside a transaction
爲什麼psycopg2報告事務仍在進行中?有什麼不同的方式我應該關閉psql事務?
如果我不運行shp2pgsql子處理命令,con.autocommit
執行成功。默認情況下,shp2pgsql是否將事務打開到某個位置? (http://www.bostongis.com/pgsql2shp_shp2pgsql_quickguide.bqg不建議這樣做)
pg_locks
中沒有相關條目存在,表明存在停滯/空閒事務。我不使用shp2pgsql函數中的psycopg2連接對象。而且,如果我的shp2pgsql功能後重新創建一個新的連接對象
con = psycopg2.connect(host=db_host, user=db_user, password=db_pass, database=db_name)
,con.autocommit=True
工作正常。
編輯:我當然可以在所有shp2pgsql導入完成後簡單地創建psycopg2連接對象,但這在我的代碼中並不理想,我寧願理解發生了什麼。
編輯2:在打開psycopg2連接後立即設置con.autocommit=True
,而不是稍後,繞過此錯誤。
EDIT3:添加MWE
import psycopg2
import os
import subprocess
from glob import glob
def vacuum(con, table=""):
autocommit_orig = con.autocommit
con.autocommit = True
with con.cursor() as cur:
cur.execute("VACUUM ANALYZE {};".format(table))
con.autocommit = autocommit_orig
def read_shapefile(path, tablename, srid="4269"):
command = "shp2pgsql -s {} -a -D -W LATIN1 {} {} | psql -h {} -d {} -U {}".format(srid, path, tablename, host, dbname, user)
p=subprocess.Popen(command, shell=True)
p.communicate()
def load_data(con, datapath):
dir = os.path.join(datapath,dataname)
shapefiles = glob(os.path.join(dir,"*.shp"))
for shapefile in shapefiles:
read_shapefile(shapefile, tablename)
if __name__ == "__main__":
con = psycopg2.connect(host=db_host, user=db_user, password=db_pass, database=db_name)
load_data(con, datapath)
vacuum(con, tablename)
你可以爲此發佈MWE嗎?我想確定我理解代碼的佈局。 – Richard
我在原帖中添加了以上MWE。 –