Как обрабатывать HTML как значение в запросе на вставку PostgreSQL? - PullRequest
0 голосов
/ 13 июня 2019

У меня есть Pandas DataFrame со многими столбцами, из которых один столбец является «значением», содержащим веб-страницу HTML. Я выполняю запрос Upsert для каждой строки DataFrame, но получаю следующую ошибку:

Я пытался экранировать HTML с помощью следующих методов:

  1. df.value = df.value.apply(lambda x: re.escape(x))
  2. df.value = df.value.apply(lambda x: MySQLdb.escape_string(x))

Вот моя функция:

non_key_cols = df.columns.tolist()
    non_key_cols.remove(primary_key)

#    df.value = df.value.apply(lambda x: re.escape(x))    
    df.value = df.value.apply(lambda x: MySQLdb.escape_string(x))

    enclose_with_quote = [True if type_name.name=='object' else False for type_name in df.dtypes]
    all_cols = df.columns.tolist()
    #enclose df columns in inverted commas
    for i in range(len(enclose_with_quote)):
        if enclose_with_quote[i]:
            df[all_cols[i]] = df[all_cols[i]].apply(lambda x: '"' + x + '"')
        else:
            df[all_cols[i]] = df[all_cols[i]].apply(lambda x: str(x))


    sql = "INSERT INTO " \
    + tablename \
    + "(" + ", ".join([col for col in df.columns]) + ")" \
    + " VALUES " \
    + ", ".join(["(" + ", ".join(list(row)) + ")" for row in df.itertuples(index=False, name=None)]) \
    + " ON CONFLICT (" + primary_key + ") DO UPDATE SET " \
    + ", ".join([col + "=EXCLUDED." + col for col in non_key_cols])

    conn = _getpostgres_connection()
    cur = conn.cursor()
    cur.execute(sql)
    cur.close()
    conn.commit()
    conn.close()

Это ошибка, которую я получаю:

 ProgrammingError: syntax error at or near "margin" LINE 1:
 ...t_of_nums_not_in_table_regex) VALUES ("<p style=\"margin: 0p...

1 Ответ

0 голосов
/ 14 июня 2019

Проблема, при которой вы пишете строку в двойных кавычках. В Postgres двойные кавычки означают имя столбца / таблицы. Вам придется использовать одинарные кавычки для строк.

if enclose_with_quote[i]:
        df[all_cols[i]] = df[all_cols[i]].apply(lambda x: "'" + x + "'")

При этом вы получите ошибку, если ваша строка содержит одинарные кавычки. Самый безопасный и простой способ - использовать параметризованный запрос, который будет обрабатывать кавычки, экранирующие себя. Еще посмотрите этот пост для использования пользовательского разделителя строк.

...