2011-05-24 58 views
8

我已经在插入数据到我的数据库打一个大减速。你可以从下面的代码中看到,我只是构建了要传递给execute命令的SQL语句。值是正确的,一切都很好,但python解释器似乎在运行时添加和删除引号。INSERT INTO和字符串连接与Python

这是到数据库中插入空间数据的正确方法。

INSERT INTO my_table(
      name, url, id, point_geom, poly_geom) 
    VALUES ('test', 'http://myurl', '26971012', 
      ST_GeomFromText('POINT(52.147400 19.050780)',4326), 
      ST_GeomFromText('POLYGON((52.146542 19.050557, bleh, bleh, bleh))',4326)); 

这是Postgres的查询编辑器可验证......现在,当我运行Python代码低于它增加了双引号的ST_GeomFromText功能,然后删除ID列的报价。

INSERT INTO my_table(
      name, url, id, point_geom, poly_geom) 
    VALUES ('test', 'http://myurl', 26971012, 
    "ST_GeomFromText('POINT(52.147400 19.050780)',4326)", 
    "ST_GeomFromText('POLYGON((52.146542 19.050557, 52.148430 19.045527, 52.149525 19.045831, 52.147400 19.050780, 52.147400 19.050780, 52.146542 19.050557))',4326)"); 

这会导致插入失败,并且PostGIS声称它不是合适的几何体。当我在屏幕上打印每一个参数时,引用并没有什么好笑的,所以我认为问题必须在执行命令中。我正在使用Python 2.7 ...任何人都可以借助如何防止这种疯狂继续吗?

conn = psycopg2.connect('dbname=mydb user=postgres password=password') 
    cur = conn.cursor() 
    SQL = 'INSERT INTO my_table (name, url, id, point_geom, poly_geom) VALUES (%s,%s,%s,%s,%s);' 
    Data = name, url, id, point, polygon 
    #print Data 
    cur.execute(SQL, Data) 
    conn.commit() 
    cur.close() 
    conn.close() 
+0

我试图cur.execute(SQL,(数据)),但将引发元组索引超出范围。任何人? – aeupinhere 2011-05-24 22:46:06

回答

13

您传递字符串ST_GeomFromText('POINT(..)')作为参数,并psycopg2是逃避它。但ST_GeomFromText(..)是PostGIS函数,而不是要插入的数据。

要解决这个问题,你需要将ST_GeomFromText功能移动到静态SQL。例如:

sql = ''' 
    INSERT INTO foo (point_geom, poly_geom) 
    VALUES (ST_PointFromText(%s, 4326), ST_GeomFromText(%s, 4326))''' 
params = ['POINT(20 20)', 'POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'] 
cur.execute(sql, params) 
+0

这绝对解决了它!谢谢一堆...... – aeupinhere 2011-05-25 12:37:14

+0

它确实有效,应该被接受为答案。 – Alex 2015-07-03 07:17:24

+0

这个答案非常有用。我得到了它的工作,但是当我在插入后查看pgadmin中的数据时,没有看到为字段定义的几何类型或srid?这是否必须分开进行? – kflaw 2016-05-25 15:20:40

0

这是更好(编辑:比你在做什么,不超过1回答)做这样的事情:

select st_asgeojson(the_geom_ls) from atlas where the_geom_ls &&\ 
st_geomfromtext('POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))', 4326) 

,并传递到您的适配器与在COORDS一个元组,它们将被正确解析。这是迄今为止最不痛苦的做法。如果你真的有单独构建字符串,您可通过浏览清理逸出的cur.mogrify输出:

cur.mogrify('INSERT INTO my_table (name, url, id, point_geom, poly_geom) VALUES (%s,%s,%s,%s,%s);', (1,2,3,4,5)) 
>>>'INSERT INTO my_table (name, url, id, point_geom, poly_geom) VALUES (1,2,3,4,5);' 

query = "ST_GeomFromText('POLYGON((52.146542 19.050557, 52.148430 19.045527, 52.149525 19.045831, 52.147400 19.050780, 52.147400 19.050780, 52.146542 19.050557))',4326)" 

cur.mogrify('INSERT INTO my_table (name, url, id, point_geom, poly_geom) VALUES (%s,%s,%s,%s,%s);', (1,2,3,4,query)) 
>>> "INSERT INTO my_table (name, url, id, point_geom, poly_geom) VALUES (1,2,3,4,E'ST_GeomFromText(''POLYGON((52.146542 19.050557, 52.148430 19.045527, 52.149525 19.045831, 52.147400 19.050780, 52.147400 19.050780, 52.146542 19.050557))'',4326)');" 

抵制使用字符串上的SQL查询字符串格式化方法的诱惑,即使这些东西可能令人沮丧。

+0

我没有得到尝试这种方法的机会,但下次我遇到类似的情况时,我一定会看看它!亚当 – aeupinhere 2011-05-25 12:38:14

+0

@samplebias答案是更好的(他似乎疯狂知道一般);我使用上面的简单矩形,对于一般情况,最好是使用通用的“POLYGON({0})”格式(some_geometry)方法。如果你对psycopg2如何逃离事物感到困惑,请看'cur.mogrify'方法。 – unmounted 2011-05-25 20:48:06

+0

@bvmou我试试这个方法与cur.execute和一个类似的例子,但我已经从'psycopg2.InternalError错误:ERREUR:解析错误 - 无效geometry':因为E'ST_GeomFromText无法识别......为什么E”当我替换变量? – reyman64 2012-11-08 17:13:16