psycopg SQL 查询 WKB 字符串时出现语法错误
Syntax error with psycopg SQL query over a WKB string
我的代码执行一个简单的 SQL 查询以将一些 WKB 几何图形转换为 WKT。我从 url 请求中获取 WKB 几何图形。代码如下所示:
url = 'http://..........'
response = urllib2.urlopen(url).read()
responseJson = json.loads(response)
coordWKB = responseJson['wkb_geometry']
print(coordWKB)
cur.execute("SELECT ST_AsText(" + coordWKB + ")")
coordWKB
看起来像这样:
'0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........'
但是我得到以下错误:
psycopg2.ProgrammingError: syntax error at or near "A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC11................
LINE 1: ...000020E6100000010000000103000000010000001200000017A84D0F3992...
如果我执行下面的代码,它会起作用:
cur.execute("select ST_AsText('0106000020E6100000010000000103000000010000001200000017A84D0F39925EC08.............')")
我似乎无法弄清楚我正在传递查询的 WKB 有什么问题。
先读Understanding repr( ) function in Python。字符串 coordWKB
'0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........'
不包括单引号,这只是您的 python 解释器为方便起见显示字符串值的方式。如果它包含单引号,那么它将显示为:
"'0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........'"
考虑到这一点
cur.execute("SELECT ST_AsText(" + coordWKB + ")")
结果 SQL 将是:
SELECT ST_AsText(0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........)
应该很明显这是错误的。
接下来你应该阅读little Bobby Tables and "the problem with the query parameters". You should never include values in your SQL query by concatenating strings. That opens up the doors for SQL injection. The values have to be properly escaped so that no additional SQL can be injected to your query. That is a job for your DB-API and all you have to do is instruct it with placeholders. From basic usage of psycopg2的故事:
# Pass data to fill a query placeholders and let Psycopg perform
# the correct conversion (no more SQL injections!)
>>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)",
... (100, "abc'def"))
请注意,您没有自己格式化查询字符串,而是将值元组作为参数传递给 cur.execute
。这样你的原始查询应该写成:
cur.execute("SELECT ST_AsText(%s)", (coordWKB,))
我的代码执行一个简单的 SQL 查询以将一些 WKB 几何图形转换为 WKT。我从 url 请求中获取 WKB 几何图形。代码如下所示:
url = 'http://..........'
response = urllib2.urlopen(url).read()
responseJson = json.loads(response)
coordWKB = responseJson['wkb_geometry']
print(coordWKB)
cur.execute("SELECT ST_AsText(" + coordWKB + ")")
coordWKB
看起来像这样:
'0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........'
但是我得到以下错误:
psycopg2.ProgrammingError: syntax error at or near "A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC11................
LINE 1: ...000020E6100000010000000103000000010000001200000017A84D0F3992...
如果我执行下面的代码,它会起作用:
cur.execute("select ST_AsText('0106000020E6100000010000000103000000010000001200000017A84D0F39925EC08.............')")
我似乎无法弄清楚我正在传递查询的 WKB 有什么问题。
先读Understanding repr( ) function in Python。字符串 coordWKB
'0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........'
不包括单引号,这只是您的 python 解释器为方便起见显示字符串值的方式。如果它包含单引号,那么它将显示为:
"'0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........'"
考虑到这一点
cur.execute("SELECT ST_AsText(" + coordWKB + ")")
结果 SQL 将是:
SELECT ST_AsText(0106000020E6100000010000000103000000010000001200000017A84D0F39925EC083FC69A455C342400A1451BC48925EC0422CDC116B........)
应该很明显这是错误的。
接下来你应该阅读little Bobby Tables and "the problem with the query parameters". You should never include values in your SQL query by concatenating strings. That opens up the doors for SQL injection. The values have to be properly escaped so that no additional SQL can be injected to your query. That is a job for your DB-API and all you have to do is instruct it with placeholders. From basic usage of psycopg2的故事:
# Pass data to fill a query placeholders and let Psycopg perform
# the correct conversion (no more SQL injections!)
>>> cur.execute("INSERT INTO test (num, data) VALUES (%s, %s)",
... (100, "abc'def"))
请注意,您没有自己格式化查询字符串,而是将值元组作为参数传递给 cur.execute
。这样你的原始查询应该写成:
cur.execute("SELECT ST_AsText(%s)", (coordWKB,))