【问题标题】:Python pandas not importing values as is on OraclePython pandas 没有像在 Oracle 上那样导入值
【发布时间】:2021-10-31 06:33:37
【问题描述】:

我在我的 python 脚本中导入了一个 txt 文件,然后将其转换为数据框。然后我创建了一个函数,它使用 cx_oracle 更快地将我的数据插入到 Oracle 数据库中。它工作得很好,只需要 15 分钟即可导入 100 万+ 个数据 - 但它不会按原样复制值。这是该代码的一部分:

sqlquery = 'INSERT INTO {} VALUES({})'.format(tablename, inserttext)
df_list = df.values.tolist()
cur = con.cursor()

cur.execute(sql_query1)
logger.info("Completed: %s", sql_query1)

for b in df_list :

    for index, value in enumerate(b):
        if isinstance(value, float) and math.isnan(value):
            b[index] = None
        elif isinstance(value, type(pd.NaT)):
            b[index] = None

这是我所期望的示例数据:

DATE STORE COST PARTIAL
16-JUN-21 08.00.00.000000000 PM 00006 +00000.0082 false

但这是被导入的

DATE STORE COST PARTIAL
16-JUN-21 6 0.0082 F

我需要它与零、符号等完全相同。我已经尝试通过 df = df.astype(str) 将数据帧转换为字符串,但它不起作用。

希望你能帮忙!

【问题讨论】:

  • 我建议在导入之前将表上的列数据类型更改为字符串,因为 python 对数据类型进行了假设。
  • 如果要存储字符串,请将所有 Oracle 数据库列类型设为 VARCHAR2。
  • 是的,所有列都在字符串中,这就是为什么我也不确定为什么它不只是采用我导入的格式。

标签: python oracle scripting spyder cx-oracle


【解决方案1】:

如果不考虑架构设计和架构是否真的是您应该使用的,那么使用此架构:

create table t (d varchar2(31), s varchar2(6), c varchar(12), p varchar(5));

这个数据在t.csv:

16-JUN-21 08.00.00.000000000 PM,00006,+00000.0082,false

还有这段代码:

import cx_Oracle
import os
import sys
import csv

if sys.platform.startswith("darwin"):
    cx_Oracle.init_oracle_client(lib_dir=os.environ.get("HOME")+"/Downloads/instantclient_19_8")

username = os.environ.get("PYTHON_USERNAME")
password = os.environ.get("PYTHON_PASSWORD")
connect_string = os.environ.get("PYTHON_CONNECTSTRING")

connection = cx_Oracle.connect(username, password, connect_string)

with connection.cursor() as cursor:

    # Predefine the memory areas to match the table definition
    cursor.setinputsizes(31,6,12,5)

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

    with open('t.csv', 'r') as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=',')
        sql = "insert into t (d, s, c, p) values (:1, :2, :3, :4)"
        data = []
        for line in csv_reader:
            data.append(line)
            if len(data) % batch_size == 0:
                cursor.executemany(sql, data)
                data = []
        if data:
            cursor.executemany(sql, data)
        connection.commit()

with connection.cursor() as cursor:
    sql = """select * from t"""
    for r in cursor.execute(sql):
        print(r)

输出是:

('16-JUN-21 08.00.00.000000000 PM', '00006', '+00000.0082', 'false')

有关一般参考,请参阅 cx_Oracle 文档Batch Statement Execution and Bulk Loading

【讨论】:

  • 感谢您的回答!我实际上找到了一个非常简单的解决方案哈哈哈。只需这样做:当我阅读我的 df 时,df = pd.read_csv(basepath, sep=';', index_col = False, header=0, nrows=5, dtype=str)。
猜你喜欢
  • 2016-10-22
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 2016-10-25
  • 2021-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多