使用python将庞大的XLS数据加载到Oracle中

使用python将庞大的XLS数据加载到Oracle中,python,oracle,cx-oracle,Python,Oracle,Cx Oracle,我有一个300多万条记录的XLS文件,我需要使用Python2.7将其转储到Oracle12CDB(直接转储)中 我正在使用Cx_Oracle python包建立与Oracle的连接,但是读取和转储XLS(使用openpyxl pckg)的速度非常慢,对于成千上万条记录来说,性能会下降 从脚本编写的角度来看,使用了两种方法- 我尝试过批量加载,读取数组中的所有值,然后使用游标prepare(带绑定变量)和游标fetchmany转储它。这在处理海量数据时效果不佳 在提取数据时反复加载数据。即使这种

我有一个300多万条记录的XLS文件,我需要使用Python2.7将其转储到Oracle12CDB(直接转储)中

我正在使用Cx_Oracle python包建立与Oracle的连接,但是读取和转储XLS(使用openpyxl pckg)的速度非常慢,对于成千上万条记录来说,性能会下降

从脚本编写的角度来看,使用了两种方法-

  • 我尝试过批量加载,读取数组中的所有值,然后使用游标prepare(带绑定变量)和游标fetchmany转储它。这在处理海量数据时效果不佳

  • 在提取数据时反复加载数据。即使这种方式也存在性能问题

  • 我可以部署哪些选项和技术/包作为从XLS加载此卷数据到Oracle DB的最佳实践?建议通过脚本加载此卷数据,还是必须使用ETL工具?
    到目前为止,我只有通过python脚本的选项,所以请回答前一个问题。如果可以将excel fila导出为CSV,那么您只需使用
    sqlldr
    将文件加载到db中即可。excel还提供ODBC支持,这样您就可以直接从excel传输到Oracle,前提是您有驱动程序。这就是说,任何涉及转换内存中的大量数据(从Excel内部使用的任何数据)然后将其传递给DB的操作都可能比专门的批量操作性能差,而专门的批量操作可以优化为使用更少的内存。浏览Python只是为任务添加了另一层(Excel到Python到Oracle),尽管可以将其设置为使用流。

    基本上,对于大容量数据,除了C之外,任何语言都会强调I/O。最好的方法是使用DB供应商提供的本机工具/实用程序。 对于oracle来说,正确的选择是SQL Loader

    有关快速教程,请参阅此链接

    下面是运行SQL Loader并返回返回代码、输出和错误的示例代码

    sql_ld_command = ['sqlldr ',  'uid/passwd', 'CONTROL=', 
    'your_ctrl_file_path', 'DATA=', 'your_data_file_path']   
    
    sql_ldr_proc  = subprocess.Popen(sql_ld_command, stdin=subprocess.PIPE,stdout=subprocess.PIPE, stderr=subprocess.PIPE)   
    
    out, err  = sql_ldr_proc.communicate()  
    retn_code = sql_ldr_proc.wait()
    

    以下是所有步骤:加载xlsx,生成csv(制表符分隔)和ctrl文件,使用sqlldr加载

    # %%
    import sys
    import pandas as pd
    import subprocess
    # %%
    user = 'in_user_name'
    password = 'in_password'
    host = 'in_host'
    database = 'in_service_name'
    in_file = r"in_file.xlsx"
    in_sheet_name = 'in_sheet'
    tablename = 'in_table'
    
    # %%
    df = pd.read_excel(in_file, sheet_name=in_sheet_name)
    print(f"Loaded {df.shape[0]} records from {in_file}")
    # %%
    inflie = f'{tablename}.csv'
    controlfile = f'{tablename}.ctrl'
    # %%,
    df.to_csv(inflie, index=False, sep='\t',)
    # %%
    columns = df.columns.tolist()
    with open(controlfile, 'w') as file:
        header = f"""OPTIONS (SKIP=1, DIRECT=TRUE ) 
    LOAD DATA
    INFILE '{inflie}' 
    BADFILE '{tablename}.bad'
    DISCARDFILE '{tablename}.dsc'
    TRUNCATE
    INTO TABLE {tablename}
    FIELDS TERMINATED BY X'9'  
    TRAILING NULLCOLS
    ( """
        file.write(header)
        for c in columns[:-1]:
            file.write(f'{c},\n')
        file.write(f'{columns[-1]})')
    # %%
    sqlldr_command = f"""sqlldr USERID='{user}/{password}@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={host})(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME ={database}) ))'  control={controlfile}"""
    print(f"Running sqlldr. Log file: {tablename}.log")
    subprocess.call(sqlldr_command, shell=True)
    

    自动将XLSX导出到CSV,如前面的回答中所述。但是,与其调用sqlldr脚本,不如创建一个使用sqlldr代码的外部表。每次从中选择表格时,它都会从CSV加载表格。

    这是最好的选择。您能否将
    xls
    转换为
    csv
    ,或者结构是否存在问题,需要您进行一些预处理?Python有时可能感觉速度很快,但当您有一个庞大的表时,它会使您的速度减慢。您应该通过oracles
    sqlldr
    进行引导,该工具针对加载进行了优化,速度会快得多。我可以将XLS转换为CSV。我可以在查看批处理文件自动化解决方案时从Python调用SQL loader吗?您不需要Python,sqlldr是一种oracle工具,用于在db中加载数据,速度非常快。有关sqlldr的一些信息:*Loader\u常见问题解答。最好与dba讨论如何使用sqlldrYeah,但是,有人每次都必须通过sqlldr手动上传CSV。我正在寻找一种更自动化的解决方案,其中cron作业在给定时间运行脚本Python的性能不好,无法加载巨大的数据文件。使用sqlldr并生成一个批处理脚本。Python脚本在内部调用该脚本,然后再继续其他操作转换,所以成功了。谢谢!