使用Python将数据从Excel导入Oracle表

时间:2017-10-20 17:46:18

标签: python excel oracle python-3.6 cx-oracle

对等体,

新手在这里。有没有办法可以从excel文件中读取数据并加载到Oracle表中?一些示例python脚本会有很大帮助。我编写了几行代码来熟悉,如下所示。

P.S。编辑:我的意思是这只是我的部分代码。我不确定如何在Oracle部分中将“insert statement”或“create table”语句作为此代码的一部分。我想在每个列的循环中从excel读取数据时加载数据。 TIA!

import openpyxl
import cx_Oracle

#Oracle connection starts here
connection = cx_Oracle.connect("<schema>", "<pwd>", "<hostname>/<sid/service>")
print("Database version:", connection.version)
print(cx_Oracle.version)
print(connection.current_schema)

# creating a table
create_table = """
CREATE TABLE test (
col1 VARCHAR2(50) NOT NULL,
col2 VARCHAR2(50) NOT NULL,
col3 VARCHAR2(50) NOT NULL,
col4 VARCHAR2(50) NOT NULL,
col5 VARCHAR2(50) NOT NULL,
col6 VARCHAR2(50) NOT NULL,
col7 VARCHAR2(50) NOT NULL
)
"""
from sys import modules
cursor.execute(create_table)    

from openpyxl import Workbook
wb = openpyxl.load_workbook('<name of the file>',data_only=True)
ws = wb['Sheet1']

x=1
m=1

# looping through each column
for j in range(2,ws.max_column+1):

   ID = m 
   col1 = ws.cell(row=x,column=j).value  
   m = m+1

   col2 = ws.cell(row=1, column=j).value

   col3 = ws.cell(row=2, column=j).value

   col4 = ws.cell(row=3,column=j).value

   col5 = ws.cell(row=4, column=j).value

   col6 = ws.cell(row=5, column=j).value

   col7 = ws.cell(row=6, column=j).value

   #looping through each row for each column      
   for i in range(1,ws.max_row+1):
         Cellval= ws.cell(row=i, column=j).value

# Inserting all the above variables for each column loop
insert_table="""
INSERT INTO test (col1,col2,col3,col4,col5,col6,col7)
VALUES ("""+col1+""",
"""+col2+""",
"""+col3+""",
"""+col4+""",
"""+col5+""",
"""+col6+""",
"""+col7+""")"""

cursor.execute(insert_table)

x=x+1

connection.close()

我说得对吗?

2 个答案:

答案 0 :(得分:1)

您可能更喜欢直接(每行每一列都不需要循环)和性能更高的(使用cursor.executemany函数)方法使用数据分析库(pandas),如下所示:

import pandas as pd
import cx_Oracle    
connection = cx_Oracle.connect("<schema>", "<pwd>", "<hostname>/<sid/service>")
cursor = connection.cursor()    
file = r'C:\\path\\ToFile\\myFile.xlsx'        
tab_name = "TEST"
tab_exists = """
DECLARE
  v_exst INT;
BEGIN
  SELECT COUNT(*) 
    INTO v_exst 
    FROM cat 
   WHERE table_name = '"""+tab_name+"""' 
     AND table_type = 'TABLE';
  IF v_exst = 1 THEN
     EXECUTE IMMEDIATE('DROP TABLE """+tab_name+"""');
  END IF;   
END;
"""
cursor.execute(tab_exists)    
create_table = """
CREATE TABLE """+tab_name+""" (
       col1 VARCHAR2(50) NOT NULL,
       col2 VARCHAR2(50) NOT NULL,
       col3 VARCHAR2(50) NOT NULL,
       col4 VARCHAR2(50) NOT NULL,
       col5 VARCHAR2(50) NOT NULL,
       col6 VARCHAR2(50) NOT NULL,
       col7 VARCHAR2(50) NOT NULL
)    """    
cursor.execute(create_table)     
insert_table = "INSERT INTO "+tab_name+" VALUES (:1,:2,:3,:4,:5,:6,:7)"    
df = pd.read_excel(file)    
df_list = df.fillna('').values.tolist()    
cursor.executemany(insert_table,df_list)    
cursor.close()
connection.commit()
connection.close()

还添加了删除TEST表是否存在的情况(不要忘记小心处理删除表)。

如果有多个工作表,并且需要将工作表的所有内容插入到表中,则在创建表(cursor.execute(create_table))之后,用以下内容替换代码的尾部: / p>

xl = pd.ExcelFile(file)
ls = list(xl.sheet_names)
insert_table = "INSERT INTO "+tab_name+" VALUES(:1,:2,:3,:4,:5,:6,:7)"
for i in ls:
    df = pd.read_excel(file,sheet_name=i)
    df_list = df.fillna('').values.tolist()
    cursor.executemany(insert_table,df_list)    
cursor.close()
connection.commit()
connection.close()

答案 1 :(得分:0)

考虑以下变化:

  • 通过向下运行行并反复分配列值然后追加每一行来反转嵌套的for循环。
  • 在行方式循环中缩进execute行。
  • .commit()CREATE TABLE等任何操作查询使用INSERT INTO来传播更改。
  • 使用.execute(query, params)中的第二个参数来参数化您的查询,该参数不仅可以隔离SQL注入(如果Excel单元格由聪明的用户提供恶意代码),还可以避免字符串连接和引用机箱以获得更清晰的代码。见Oracle+Python docs

调整后的代码

# looping through each row for each column      
for i in range(1, ws.max_row+1):
   for j in range(2, ws.max_column+1):       
      col1 = ws.cell(row=i, column=j).value  
      col2 = ws.cell(row=i, column=j).value
      col3 = ws.cell(row=i, column=j).value
      col4 = ws.cell(row=i, column=j).value
      col5 = ws.cell(row=i, column=j).value
      col6 = ws.cell(row=i, column=j).value
      col7 = ws.cell(row=i, column=j).value

   insert_table = "INSERT INTO test (col1, col2, col3, col4, col5, col6, col7)" + \
                  " VALUES (:1, :2, :3, :4, :5, :6, :7)"

   cursor.execute(insert_table, (col1, col2, col3, col4, col5, col6, col7))
   connection.commit()

connection.close()