python中oracle的使用过程中报错总结.
- DatabaseError: DPI-1047错误.环境配置问题
cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: “libclntsh.so: cannot open shared object file: No such file or directory”. See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help
网上差了很多资料, 很多人发生这个错误的原因是python版本与oracle不符,python是32位oracle是64位,或者python是64未而oracle是32位导致的. 不过从报错信息来开确实是这个方向
但我引发这个问题的原因不是因为版本问题,而是因为没有oracle环境
从报错信息中可分析出, 根本原因是缺少 "libclntsh.so"库的引用, libclntsh.so是oracle的核心引用.
oracle的使用前提条件,不管是windows系统还是linux,ubutu, 系统本身要先安装oracle环境,如果系统没有环境.单通过pip install cx_Oracle是没有用的. 通过python的pip下载的cx_Oracle,只是和oracle建立引用关系,让python可以访问oracle数据库, 真实的使用还是系统的oracle
系统安装oracle也是个曲折的过程.网上也有很多的教程,在此发布一个linux现成的配置好的oracle环境.(本人的是ubuntu系统)
百度网盘链接: https://pan.baidu.com/s/1wk0nt8Iy8bQIXC101y9CHg
提取码: zuv5
将该oracle文件放在/usr/lib/ 下即可
配置环境变量,引用oracle
在/etc/profile文件最后加入如下环境变量配置
export ORACLE_HOME=/usr/lib/oracle/11.2/client64 export
LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH export
PATH=$ORACLE_HOME/bin:$PATH
然后执行 source /etc/profile 加载下配置文件即可
- oracle编码错误
UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 0-1: ordinal not in range(128)
该错误是oracle编码的错误,有趣的是,我程序本地执行不报该错误,但是用pyinstaller打包后的程序报错,这也说明了是需要配置系统的编码格式
在程序创建初始化的连接oracle的时候设置编码即可
import os
os.environ['NLS_LANG'] = 'GERMAN_GERMANY.UTF8'
在有编码问题就是在创建oracle连接的时候指定编码格式encoding=‘utf-8’
- oracle在插入insert数据时报错 The ‘oracle’ dialect with current database version settings does not support empty inserts.(roacle不允许空插入)的错误
错误示例
Session.execute(User.insert(), {
"NAME": "ITS",
"AGE": 20,
"CAEATE_TIME": datetime.datetime.now()
})
# AGE在表结构类型是VARCHAR(字符串类型), 不是int类型
# CARATE_TIME 表结构类型为timestamp类型
sql = """INSERT INTO User(NAME, AGE, CREATE_TIME)
VALUES('ZS', 18, '{}')""" .format(datetime.datetime.now().replace(microsecond=0))
报错
The ‘oracle’ dialect with current database version settings does not support empty inserts.
…
以上有两处错误,都会引发"The ‘oracle’ dialect with current database version settings does not support empty inserts."错误
- 插入数据格式与表字段结构类型不符,例如AGE字段,表结构是VARCHAR类型,插入的结果确实INT类型
- 时间格式不对, oracle中表结构为timestamp日期时间类型的,插入数据时要用以下格式
‘to_date(‘2021-11-30 10:10:10’, ‘yyyy-mm-dd hh24:mi:ss’)’
时间格式不对
(cx_Oracle.DatabaseError) ORA-01843: not a valid month
…
时间格式不正确也会报类似的错误
正确写法
sql = """INSERT INTO User(NAME, AGE, CREATE_TIME)
VALUES('ZS', '18', to_date('{}', 'yyyy-mm-dd hh24:mi:ss'))""".format(datetime.datetime.now().replace(microsecond=0))
- oracle执行INSER或者UPDATE报ORA-00917: missing comma缺少逗号错误
sql = """INSERT INTO User(NAME, CREATE_TIME) VALUES('ZS', {})""".format(datetime.datetime.now())
Session.execute(sql)
报错
(cx_Oracle.DatabaseError) ORA-00917: missing comma
原因: {}缺少’ ’ 引号导致, oracle的时间格式需要用’'括起来,一般的时间格式为 ‘%Y-%m-%d %H:%M:%S’, 会产生歧义
正确写法:
sql = """INSERT INTO User(NAME, CREATE_TIME) VALUES('ZS', '{}')""".format(datetime.datetime.now())
Session.execute(sql)
- oracle查询或删除时"表或视图不存在"错误
sql = 'drop table USER'
session.execute(sql)
报错如下
(cx_Oracle.DatabaseError) ORA-00942: table or view does not exist
原因是Oracle 默认把sql语句的表名、字段名等等换成大写的,而Oracle又是大小写敏感的,解决办法是给表名加上双引号“”。之所以会产生这样的原因,是所创建的表结构或者表名中包含了小写,如果使用sqlalchemy这样的工具创建,会在创建时认为你需要区分大小写,所以在创建的表名或者字段名自动加双引号,就导致查询的时候也需要加上双引号。
总结来说,就是表字段或者表名的大小写问题。
正确写法
sql = 'drop table "USER"'
session.execute(sql)
- oracle的sql语句ORA-00933: SQL command not properly ended(“未正确结束”)错误
sql = 'drop table "USER";'
session.execute(sql)
(cx_Oracle.DatabaseError) ORA-00933: SQL command not properly ended
原因: oracle的sql语句与mysql不同,不需要以";"封号结尾
正确写法
sql = 'drop table "USER"'
session.execute(sql)
- ORA-21561:oracle连接不成功问题
报错如下
(cx_Oracle.DatabaseError) ORA-21561: OID-Generierung nicht erfolgreich
在本地环境执行程序的时候不报错,在服务器执行却报这个错误,查询后发现主要原因是服务器的hostname与 /etc/hosts 中配置不一样
举个例子:
在终端执行
╰─○ hostname # (命令)
aa # (结果)
查询hosts文件
╰─○ cat /etc/hosts # (命令)
127.0.0.1 bb # (结果)
127.0.1.1 ubuntu-virtual-machine
通过上述可以发现,查看当前用户名为"aa", 但配置hosts中 172.0.0.1却为"bb", 所以报错.
原因: hostname和hosts文件里的hostname不一致
正确解决方法: 修改hostname与hosts里保持一致
sudo scutil --set HostName bb
或者修改hosts文件与hostname保持一致
- ORA-01861格式不匹配问题
错误描述
(cx_Oracle.DatabaseError) ORA-01861: Literal stimmt nicht mit Formatzeichenfolge überein
这个问题主要发生在插入或者更新数据的时候
问题产生原因: 插入数据字段的类型与表结果字段类型不一致
解决方法:仔细排查一下数据结构是否一致
- sqlalchemy中创建oracle的ORM模型语法错误
执行过程中的错误
cx_Oracle.DatabaseError: ORA-00906: missing left parenthesis
这个错误的发生纯属个人问题
在使用oracle的时候,遇到这个错误是因为sql语句写错了,是属于语法的问题. 因为我是借助sqlalchemy建立Base的ORM模型, 用session的方式写入. 在建表过程中Base.metadata.create_all()包的错
我是这样写的
错误示例
class xxx(Base):
__tablename__ = "xxxx"
aa = Column(String)
正确应该是这样
class xxx(Base):
__tablename__ = "xxxx"
aa = Column(String(128))
纯属语法错误
- oracle主键已存在错误
cx_Oracle.IntegrityError: ORA-00001: Unique Constraint (HD_KPI.SYS_C0013385) verletzt
原因: 在插入数据的时候,插入了表中已有的主键数据,因为主键是唯一的