在Postgres中处理报价

时间:2018-06-19 14:10:09

标签: python python-3.x postgresql psycopg2

我正在尝试编写一个将字典列表向上插入postgres的函数,但是我很难处理引号。

我具有以下两个功能,一个用于生成插入语句,另一个用于执行。

import psycopg2 as pg
import string

def create_insert_sql(record, table, on_key):
    """creates the sql insert statement"""

    columns = list(record.keys())
    insert_columns = ','.join([str(x) for x in columns])
    columns.remove(on_key)
    update_set = ','.join([str(x) for x in columns])
    exclude_set = ','.join(['EXCLUDED.' + str(x) for x in columns])

    values = ','.join(['\'' + str(x) + '\'' for x in record.values()])

    insert_sql_statement = """
   INSERT INTO {} ({})
        VALUES ({})
        ON CONFLICT ({})
        DO UPDATE SET
            ({})
            = ({}) ;
    """.format(table, insert_columns, values, on_key, update_set, exclude_set)

    return insert_sql_statement

def upsert_into_pg(dataset, table, on_key):
    """Given a list of dicts, upserts them into a table with on_key as conflict"""

    conn = pg.connect(user=XXXX,
                      password=XXXX,
                      host='127.0.0.1',
                      port=3306,
                      database='XXXX')

    cur = conn.cursor()

    try:
        for record in dataset:
            cur.execute(create_insert_sql(record, table, on_key))
    except Exception as e:
        conn.rollback()
        print(e)
    else:
        conn.commit()
        print('upsert success')
    finally:
        cur.close()
        conn.close()

错误示例

test = [
    {'a': 'structure', 'b': 'l\'iv,id', 'c': 'doll', 'd': '42'},
    {'a': '1', 'b': 'shoe', 'c': 'broke', 'd': '42'},
    {'a': 'abc', 'b': 'proc', 'c': 'moe', 'd': '42'}
]

upsert_into_pg(test, 'testing', 'a')

返回

syntax error at or near "iv"
LINE 3:         VALUES ('structure','l'iv,id','doll','42')

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我能够通过以下更改来解决它。

def upsert(cur, record, table, on_key):
    """creates the sql insert statement"""

    cols = list(record.keys())
    cols_set = ','.join([str(x) for x in cols])
    vals = [record[x] for x in cols]

    vals_str_list = ["%s"] * len(vals)
    vals_str = ", ".join(vals_str_list)

    cols.remove(on_key)
    update_set = ','.join([str(x) for x in cols])
    exclude_set = ','.join(['EXCLUDED.' + str(x) for x in cols])

    cur.execute("""INSERT INTO {table} ({cols}) 
                            VALUES ({vals_str}) 
                            ON CONFLICT ({on_key}) 
                            DO UPDATE SET ({update_set}) = ({exclude_set})""".format(table=table, cols=cols_set, vals_str=vals_str, on_key=on_key, update_set=update_set, exclude_set=exclude_set),
                   vals)