使用 cx_oracle.execute_many 发送包含多个时间戳查询的列表列表
Send a list of lists including multiple timestamp queries using cx_oracle.execute_many
我正在尝试使用 cx_oracle 从一个大列表中发送多个时间戳查询。我只看到 article 每次执行发送一个查询,但我还没有看到任何使用 executemany 执行多个查询的示例。我将如何获得多个时间戳的列表?我在下面做了以下但没有运气!
import datetime
import cx_Oracle
listrows =[
[56, 'steveJob', 'Apple', '2016-08-15 20:23:03.317909', '2015-09-08 20:46:30.456299', ''],
[32, 'markZuck', 'Faceb', '2015-09-08 20:46:30.456299', '2015-09-08 20:46:30.456299', ''],
[45, 'elonMusk', 'Tesla', '2016-02-18 16:53:20.959984', '2016-02-18 17:17:05.664715', '']
]
con = cx_Oracle.connect("system","oracle","localhost:1521/xe.oracle.docker")
cursor = con.cursor()
cursor.prepare("""INSERT INTO lifexp (age, name, lastcompany, created_at, deleted_at, turnout) VALUES (:1,:2,:3,:4,:5,:6)""")
cursor.setinputsizes(cx_Oracle.TIMESTAMP)
cursor.executemany(None, listrows)
con.commit()
cursor.close()
con.close()
我要连接的 table 设置如下:
CREATE TABLE lifexp(
age NUMBER (19,0) primary key,
name VARCHAR(256),
lastcompany VARCHAR(256),
created_at timestamp,
deleted_at timestamp,
turnout timestamp
);
我收到错误:
TypeError: expecting timestamp data
当我删除行 "cursor.setinputsizes(cx_Oracle.TIMESTAMP)" 时,我得到:
cx_Oracle.DatabaseError: ORA-01843: not a valid month
问题是您发送的是字符串,而不是时间戳值!因此,在您使用 setinputsizes() 的情况下,您是在告诉 cx_Oracle 您有时间戳值要提供....但没有提供它们。如果没有 setinputsizes() 调用,您是在告诉 Oracle 将这些字符串转换为时间戳值,但默认时间戳格式与您传递的日期格式不匹配。
您应该 (a) 将字符串转换为 Python datetime.datetime 值或 (b) 在 SQL 语句
中指定转换
将字符串转换为 Python datetime.datetime 值非常简单:
datetime.datetime.strptime("2016-08-15 20:23:03.317909", "%Y-%m-%d %H:%M:%S.%f")
在 SQL 语句中指定转换也相当简单。
cursor.prepare("""
insert into lifexp
(age, name, lastcompany, created_at, deleted_at, turnout)
VALUES (:1,:2,:3,
to_timestamp(:4, 'YYYY-MM-DD HH24:MI:SS.FF'),
to_timestamp(:5, 'YYYY-MM-DD HH24:MI:SS.FF'):6)""")
我认为第一个选项更好,但两者都适合您。
我正在尝试使用 cx_oracle 从一个大列表中发送多个时间戳查询。我只看到 article 每次执行发送一个查询,但我还没有看到任何使用 executemany 执行多个查询的示例。我将如何获得多个时间戳的列表?我在下面做了以下但没有运气!
import datetime
import cx_Oracle
listrows =[
[56, 'steveJob', 'Apple', '2016-08-15 20:23:03.317909', '2015-09-08 20:46:30.456299', ''],
[32, 'markZuck', 'Faceb', '2015-09-08 20:46:30.456299', '2015-09-08 20:46:30.456299', ''],
[45, 'elonMusk', 'Tesla', '2016-02-18 16:53:20.959984', '2016-02-18 17:17:05.664715', '']
]
con = cx_Oracle.connect("system","oracle","localhost:1521/xe.oracle.docker")
cursor = con.cursor()
cursor.prepare("""INSERT INTO lifexp (age, name, lastcompany, created_at, deleted_at, turnout) VALUES (:1,:2,:3,:4,:5,:6)""")
cursor.setinputsizes(cx_Oracle.TIMESTAMP)
cursor.executemany(None, listrows)
con.commit()
cursor.close()
con.close()
我要连接的 table 设置如下:
CREATE TABLE lifexp(
age NUMBER (19,0) primary key,
name VARCHAR(256),
lastcompany VARCHAR(256),
created_at timestamp,
deleted_at timestamp,
turnout timestamp
);
我收到错误:
TypeError: expecting timestamp data
当我删除行 "cursor.setinputsizes(cx_Oracle.TIMESTAMP)" 时,我得到:
cx_Oracle.DatabaseError: ORA-01843: not a valid month
问题是您发送的是字符串,而不是时间戳值!因此,在您使用 setinputsizes() 的情况下,您是在告诉 cx_Oracle 您有时间戳值要提供....但没有提供它们。如果没有 setinputsizes() 调用,您是在告诉 Oracle 将这些字符串转换为时间戳值,但默认时间戳格式与您传递的日期格式不匹配。
您应该 (a) 将字符串转换为 Python datetime.datetime 值或 (b) 在 SQL 语句
中指定转换将字符串转换为 Python datetime.datetime 值非常简单:
datetime.datetime.strptime("2016-08-15 20:23:03.317909", "%Y-%m-%d %H:%M:%S.%f")
在 SQL 语句中指定转换也相当简单。
cursor.prepare("""
insert into lifexp
(age, name, lastcompany, created_at, deleted_at, turnout)
VALUES (:1,:2,:3,
to_timestamp(:4, 'YYYY-MM-DD HH24:MI:SS.FF'),
to_timestamp(:5, 'YYYY-MM-DD HH24:MI:SS.FF'):6)""")
我认为第一个选项更好,但两者都适合您。