我有一个用~
分隔的纯文本文件
20-07-31-03:00~[*IF *VALUE *EQ 'DB_CONTENT' *UNTIL]
下面的脚本接收断开的数组,如下
with open('''/etc/files/plaintext.txt''') as f:
resultCollect = f.read().splitlines()
resultSplit.append([line.split('~') for line in resultCollect])
insert(resultSplit[0], table)
# resultSplit[0] --> ['20-07-31-03:00','[*IF *VALUE *EQ 'DB_CONTENT' *UNTIL]']
def insert(data, table):
val = [tuple(line) for line in data]
for i in range(len(val)):
cur.execute("""INSERT INTO {0} VALUES {1}""".format(table, tuple(val[i])))
然而,由于'DB_CONTENT'
中的字符串中有单引号,当试图插入数据库时,会生成以下错误
column "[*IF *VALUE *EQ 'DB_CONTENT' *UNTIL]" does not exist
生成的插入示例
INSERT INTO tbl_details VALUES ('20-07-30-01:53', "[*IF *VALUE *EQ 'DB_CONTENT' *UNTIL]")
可复制示例:
result = []
val = '''20-07-31-03:00~[*IF *VALUE *EQ 'DB_CONTENT' *UNTIL]'''
result.append([val.split('~')])
def insert(data, table):
val = [tuple(line) for line in data]
for i in range(len(val)):
print("""INSERT INTO {0} VALUES {1}""".format(table, tuple(val[i])))
insert(result[0], 'tbl_name')
有解决方案的建议吗?
您永远不应该自己格式化SQL查询,正如psycopg文档所说:
Never,Never,Never使用Python字符串串联(+(或字符串参数插值(%(将变量传递到SQL查询字符串。即使在枪口下也不行。
从文档示例中可以看出,首选的方法是让库处理它。
SQL = "INSERT INTO authors (name) VALUES (%s);" # Note: no quotes
data = ("O'Reilly", )
cur.execute(SQL, data) # Note: no % operator
这应该可以正确地用单引号转义字符串。
编辑:在代码中添加示例。上面提出的方法不应该用于插入表名(INSERT INTO %s
(,它应该只用于数据部分(VALUES (%s)
(
编辑2:没有注意到要插入两个值'20-07-30-01:53', "[*IF *VALUE *EQ 'DB_CONTENT' *UNTIL]"
。我已经编辑了代码,注意到查询字符串中有额外的%s
。此外,我真的看不出val[i]
包含什么,但它应该是您想要插入的两个值的序列(元组、列表(。
from psycopg2.sql import SQL, Identifier
SQL_QUERY_STRING = """INSERT INTO {} VALUES (%s, %s)"""
def insert(data, table):
val = [tuple(line) for line in data]
for i in range(len(val)):
curr.execute(
SQL(SQL_QUERY_STRING).format(Identifier(table)),
val[i],
# second (data) argument has to be a sequene (tuple, list, ...)
# of values to be inserted, even if it's just one value
)
值部分不应使用双引号。Postgres中的双引号用于表示表或列。您应该使用"转义单引号,并准备插入语句。insert语句应写成insert INTO tbl_details VALUES('20-07-30-01:53','[*IF*VALUE*EQ'DB_CONTENT''*UNTIL]'(