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

时间:2015-05-19 11:29:07

标签: python oracle cx-oracle

我有一个300万以上的记录XLS文件,我需要使用python 2.7在Oracle 12C DB(直接转储)中转储。

我正在使用Cx_Oracle python包来建立与Oracle的连接,但是读取和转储XLS(使用openpyxl pckg)非常慢,并且性能会因数千万条记录而降低。

从脚本角度来看,有两种使用方式 -

  1. 我尝试了批量加载,通过读取数组中的所有值,然后使用游标prepare(带有绑定变量)和游标fetchmany来转储它。这对大数据不起作用。

  2. 在提取数据时迭代加载数据。即使这样也存在性能问题。

  3. 我可以部署哪些选项和技术/软件包作为将此数据量从XLS加载到Oracle DB的最佳实践?是否建议通过脚本加载此数据量或者是否必须使用ETL工具? 截至目前我只有通过python脚本选项,所以请回答前者

5 个答案:

答案 0 :(得分:1)

如果可以将您的excel fila导出为CSV,那么您只需使用sqlldr在db中加载文件

答案 1 :(得分:0)

Excel还附带ODBC支持,因此您可以直接从Excel泵入Oracle,假设您有驱动程序。也就是说,任何涉及在内存中转换大量数据(从内部使用的任何Excel)然后将其传递到数据库的任何事情都可能比专门的批量操作更低性能,可以优化使用更少的内存。通过Python只需在任务中添加另一层(Excel到Python到Oracle),尽管可以将其设置为使用流。

答案 2 :(得分:0)

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

请参阅此链接以获取快速教程 http://www.thegeekstuff.com/2012/06/oracle-sqlldr/

这里你去...运行SQL Loader的示例代码,然后返回返回码,输出和放大器错误

$('.list-item').on('click', function() {
    var itemEl = $(this);
        itemEl.data('originalText', $(this).html());
        itemEl.html('Saved');

        setTimeout(function() { 
            itemEl.html(itemEl.data('originalText')) }, 5000);
  }); 

答案 3 :(得分:0)

所有步骤如下:加载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)

答案 4 :(得分:0)

如上一个答案所述,自动将XLSX导出为CSV。但是,不要再调用sqlldr脚本,而是创建一个使用sqlldr代码的外部表。每次从中选择表格,都会从CSV加载表格。