如何将变量值插入table?

How to insert a variable value into table?

假设我有以下 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 中的值插入 table

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()

我收到这个错误:

(lines[0],lines[1],lines[2]) cx_Oracle.DatabaseError: ORA-01858: a non-numeric character was found where a numeric was expected

经过一些调试后,我能够将其确定为日期问题,所以我用硬编码日期代替了行 [0],并且成功了!

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

为什么它不能使用 lines[0] 变量,但使用硬编码值却可以正常工作?

日期的字符串格式必须符合 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]))

现在您已经解决了日期格式问题,考虑使用 executemany() 提高性能。类似于:

与file.csv包含:

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

和 table 创建如下:

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 秒(主要是连接时间成本),而使用 execute()

需要 36 秒