【问题标题】:psycopg2 write list of strings (with text delimiter) to a postgres arraypsycopg2 将字符串列表(带有文本分隔符)写入 postgres 数组
【发布时间】:2020-04-17 17:33:03
【问题描述】:

目标:

我有一个包含字符串的列表,其中一些包含单引号(作为字符串本身的一部分);

listOfStr = ['A sample string', "A second string with a ' single quote", 'a third string', ...]

请注意,每个条目不一定使用相同的文本分隔符,有些是单引号,其他(包含单引号作为字符串的一部分)是双引号。

我想使用psycopg2 将我的列表插入为postgresql ARRAY

import psycopg2
connString = (...) # my DB parameters here.
conn = psycopg2.connect(connString)
curs = conn.cursor()

update_qry = ("""UPDATE "mytable" SET arraycolumn = {listofStr}::varchar[],
              timestamp = now() WHERE id = {ID}""".format(listofStr=listofStr, 
                                                          ID=ID))
curs.execute(update_qry)

问题:

但我得到这个错误:

SyntaxError: syntax error at or near "["
LINE 1: UPDATE "mytable" SET arraycolumn = ['A sample string'...

如果我通过在列表前面添加单词“ARRAY”在 SQL 查询中指定 ARRAY 数据类型:

update_qry = ("""UPDATE "mytable" SET arraycolumn = ARRAY {listofStr}::varchar[],
              timestamp = now() WHERE id = {ID}""".format(listofStr=listofStr, 
                                                          ID=ID))

我得到这个错误:

UndefinedColumn: column "A second string with a ' single quote" does not exist
LINE 1: 'A sample string', "A second string with a '...

我不知道如何解决它。

环境:

  • Ubuntu 18.04 64 位 5.0.0-37-generic x86_64 GNU/Linux
  • Python 3.6.9(默认,2019 年 11 月 7 日,10:44:02)
  • psycopg2 2.7.7
  • psycopg2-二进制 2.8.4
  • "PostgreSQL 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1) on x86_64-pc-linux-gnu, gcc 编译 (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0, 64-bit" 李>

相关主题:

Postgres/psycopg2 - Inserting array of strings

文档:

http://initd.org/psycopg/docs/usage.html -> #列表适配

【问题讨论】:

    标签: arrays python-3.x postgresql psycopg2


    【解决方案1】:

    我同意@piro 你真的想要绑定参数, 而不是试图做任何疯狂的引用。

    您已经知道如何在插入时完成该操作 每个列表元素一个简单的 VARCHAR 行。 我建议您创建一个 TEMP TABLE 和 以这种方式将您的数据发送到数据库。

    那就咨询https://www.postgresql.org/docs/current/sql-expressions.html#SQL-SYNTAX-ARRAY-CONSTRUCTORS 并使用此示例将临时表的行转换为数组:

    SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
    

    你会想要一个类似的表达式

    SELECT ARRAY(SELECT my_text FROM my_temp_table);
    

    您的临时表可能还需要一个整数列, 保持元素顺序。

    【讨论】:

    • 不幸的是,我的列表来自外部来源,我没有引用任何其他内容。我刚刚注意到一些元素是单引号和其他双引号,因为单引号作为元素的一部分存在。
    • 对。我指出您可以将其分解为两个问题。 (1.) 使用绑定参数将任意文本存储为 VARCHAR 行是您已经知道如何解决的问题。并且 (2.) 将许多 VARCHAR 行转换为单个 ARRAY 是 ARRAY-CONSTRUCTOR 文档提供解决方案的问题。
    【解决方案2】:

    基本上,该问题应该已作为重复项关闭。但是,您知道 Piro 的答案,我认为您在解释它时遇到了问题。

    id = 1
    list_of_str = ['A sample string', "A second string with a ' single quote", 'a third string']
    update_qry = """
        UPDATE mytable
        SET arraycolumn = %s,
        timestamp = now() 
        WHERE id = %s
        """
    
    cur = conn.cursor()
    cur.execute(update_qry, [list_of_str, id])
    conn.commit()
    

    【讨论】:

    • 哦,所以我们不应该使用字符串格式(在 .format()% () 之前,处理这种情况的是 psycopg2 查询本身,对吧?我们可以使用命名参数而不是位置参数吗?查询中的/cur.execute()?
    • 是的,你可以传递命名参数,见Passing parameters to SQL queries.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 2015-06-27
    • 2023-03-24
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多