如何使用to_sql将pandas dataframe写入oracle数据库?

时间:2017-11-28 21:00:18

标签: oracle pandas dataframe cx-oracle pandas-to-sql

我是一名新的甲骨文学习者。我试图将pandas数据帧写入oracle表。在网上进行研究后,我发现代码本身非常简单,但我不知道为什么我的代码不起作用。

我已从本地文件中读取了pandas数据框:

import cx_Oracle
import pandas as pd
import os

dir_path = os.path.dirname(os.path.realpath("__file__"))
df = pd.read_csv(dir_path+"/sample.csv")

现在打印df,数据帧df shold如下:

   DATE            YEAR     MONTH      SOURCE      DESTINATION
0  11/1/2017 1:00  2017     1          AL          CO  
1  11/2/2017 1:00  2017     5          GA          ID  
2  11/3/2017 1:00  2017     12         GA          MO    

然后我使用cx_Oracle创建与数据库的连接,它可以工作。接下来,我尝试将数据帧df写入表TEST。此表TEST是一个空表,已存在于oracle数据库中,它包含oracle中的DATE,YEAR,MONTH,SOURCE,DESTINATION等列。所有数据类型都与df示例数据匹配。我的代码如下:

conn_str = u'account/password@host:1521/server'
conn = cx_Oracle.connect(conn_str)

# Write records stored in a DataFrame to a oracle database
df.to_sql('TEST', conn, if_exists='replace') # the error shows here

conn.close()

显示错误:

  

DatabaseError:sql' SELECT name FROM sqlite_master上的执行失败   WHERE type =' table' AND name =?;':ORA-01036:非法变量   名称/编号

如何解决问题?非常感谢你的时间!

2 个答案:

答案 0 :(得分:4)

我在SO上看到了类似的问题 - 当您尝试使用cx_Oracle创建的连接对象写入Oracle DB时会发生这种情况。

尝试使用SQL Alchemy创建连接:

import cx_Oracle
from sqlalchemy import types, create_engine

conn = create_engine('oracle+cx_oracle://scott:tiger@host:1521/?service_name=hr')

df.to_sql('TEST', conn, if_exists='replace')

答案 1 :(得分:0)

我可以使用以下代码加载 Oracle 表:

import pandas as pd
import os

creds = {}
creds['tns_admin'] = 'Wallet_Path'
creds['sid'] = 'dev_low'
creds['user'] = 'username'
creds['password'] = pwd

os.environ['TNS_ADMIN'] = creds['tns_admin']


uri = 'oracle+cx_oracle://' + creds['user'] + ':' + creds['password'] + '@' + creds['sid']
df = pd.read_csv("test.csv")
df.to_sql('test', uri, schema='PRD', if_exists='replace')

我们需要构建并传递一个 URI,而不是连接。

注意:新的 Oracle 数据库(自治)需要钱包,所以我们需要在 TNS_ADMIN 环境变量中设置钱包路径。

此外,我不必导入 cx_Oracle,我确实仔细检查了 enter image description here

为了确保我没有被愚弄,我放下了桌子并提交了 enter image description here

我执行了上面的代码,它创建了一个包含数据的新表。