Python3: как избежать специальных символов для cx_oracle непрерывного потока инструкции insert (ORA-01756: строка в кавычках не завершается должным образом)

#python #sql #python-3.x #oracle11g #cx-oracle

#python #sql #python-3.x #oracle11g #cx-oracle

Вопрос:

Я использую код python, который считывает файл CSV и для каждой строки, которую он вставляет в базу данных Oracle.

Есть ли способ преодолеть ошибку «ORA-01756: строка в кавычках не завершается должным образом» для всех вариантов использования.

Специальными символами, которые я хочу избежать, являются одинарные кавычки (‘), двойные кавычки («), запятая (,) и другие, если это может привести к ошибке.

Моя логика на самом деле приведена ниже :

     with open(files, newline='',  encoding='utf-8') as csvfile:
        rowreader = csv.reader(csvfile, delimiter=';', quotechar='|')
        next(rowreader)
        for row in rowreader:
            values = parseCSV.input(row)
            query = "INSERT INTO MYTABLE(col1,col2) values('{val1}','{val2}')".format(**values)
            cursor.execute(query)
  

Выше не работает для вставляемой строки if — ‘my’s name’

Ответ №1:

Да — используйте параметры / привязки.

Через cx_oracle руководство по использованию привязок:

 # assuming `values` is a dict with `val1` and `val2`:
cursor.execute("INSERT INTO MYTABLE (col1, col2) values(:val1, :val2)", values)
  

Также обратите внимание, как на странице руководства написано «никогда не делайте этого !!!» что касается того, как вы интерполируете данные в свой оператор — ваш код в настоящее время также уязвим для атак SQL-инъекций.

Комментарии:

1. Большое спасибо за ваш ответ, но мои значения — это словарь. как заменить значения словаря как val1, val2

2. Согласно руководству, словарь должен работать просто отлично. cx-oracle.readthedocs.io/en/latest/user_guide /…

3. Если вы вставляете несколько записей, обязательно ознакомьтесь с документацией cx_Oracle о выполнении пакетной инструкции и массовой загрузке .

Ответ №2:

В документации есть пример, который будет намного быстрее, чем вызов execute() для каждой строки:

 import cx_Oracle
import csv

. . .

# Predefine the memory areas to match the table definition
cursor.setinputsizes(None, 25)

# Adjust the batch size to meet your memory and performance requirements
batch_size = 10000

with open('testsp.csv', 'r') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    sql = "insert into test (id,name) values (:1, :2)"
    data = []
    for line in csv_reader:
        data.append((line[0], line[1]))
        if len(data) % batch_size == 0:
            cursor.executemany(sql, data)
            data = []
    if data:
        cursor.executemany(sql, data)
    con.commit()