Как вставить значение переменной в таблицу? - PullRequest
0 голосов
/ 26 сентября 2019

Предположим, у меня есть следующий file.csv

DATE    Name    Email
26-Sep-19   Name1   Name1@email.com 
26-Sep-19   Name2   Name2@email.com 
26-Sep-19   Name3   Name3@email.com 

Я пытаюсь вставить значения из file.csv в таблицу

import cx_Oracle
import csv
import os
from datetime import datetime

con = cx_Oracle.connect(uname, pwd, hostname + ': ' + port + '/' + service)
cursor = con.cursor()

with open('file.csv', 'r') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    for lines in csv_reader:
        cursor.execute( "INSERT INTO table1 ( DATE,Name,Email) values (:1, :2, :3)", 
        (lines[0],lines[1],lines[2])  
cursor.close()
con.commit()
con.close()

Я получаю эту ошибку:

(строки [0], строки [1], строки [2]) cx_Oracle.DatabaseError: ORA-01858: не числовой символ был найден там, где ожидалось число

После некоторой отладки я смог решить проблему с датой, поэтому вместо строк [0] я заменил жестко запрограммированную дату, и она сработала!

cursor.execute( "INSERT INTO table1 ( DATE,Name,Email) values (:1, :2, :3)", 
('26-Sep-19',lines[1],lines[2])  

почемуразве он не работает с переменной lines[0], но с жестко заданным значением работает нормально?

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019

Строковый формат вашей даты должен соответствовать ожидаемому Oracle.Вы можете установить параметр NLS_DATE_FORMAT для своего сеанса или просто изменить свой код, сделав что-то вроде следующего:

cursor.execute("""
        insert into table1 (date, name, email)
        values (to_date(:1, 'dd-Mon-YY'), :2, :3)""",
        (lines[0], lines[1], lines[2]))
1 голос
/ 27 сентября 2019

Теперь, когда вы решили проблему с форматом даты, рассмотрите возможность использования executemany() для повышения производительности.Что-то вроде:

С файлом file.csv, содержащим:

26-Sep-19,Name1,Name1@email.com 
26-Sep-19,Name2,Name2@email.com 
26-Sep-19,Name3,Name3@email.com 

, и таблица, созданная как:

create table table1 ("DATE" date, name varchar2(20), email varchar2(20));

Затем этот файл использует преобразование даты, упомянутое @anthonyработает:

# Set cursor sizes to match the table definition or known max data sizes
#   create table table1 ("DATE" date, name varchar2(20), email varchar2(20));
cursor.setinputsizes(None, 20, 20)

# Adjust the batch size to meet your memory and performance requirements
batchSize = 1000

with open('file.csv', 'r') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    i = 0
    data = []
    for line in csv_reader:
        data.append((line[0],line[1],line[2]))
        i = i + 1
        if (i % batchSize == 0):
            print('batch')
            cursor.executemany("""insert into table1 ("DATE",name, email) values (to_date(:1, 'DD-Mon-YY'), :2, :3)""", data)
            data = []
            i = 0
    if (i % batchSize != 0):
        print('final')
        cursor.executemany("""insert into table1 ("DATE",name, email) values (to_date(:1, 'DD-Mon-YY'), :2, :3)""", data)
    con.commit()

Для загрузки некоторых строк в БД на дальнем краю потребовалось 4 секунды с аналогичным сценарием (в основном это время подключения) против 36 секунд с execute()

...