处理文本文件中的单引号



我有一个用~分隔的纯文本文件

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]'(

最新更新