python中oracle的使用过程中报错总结. oracle环境配置问题, oracle的sql语法问题,oracle的sql中timestamp写入问题, oracle编码问题等

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."错误

  1. 插入数据格式与表字段结构类型不符,例如AGE字段,表结构是VARCHAR类型,插入的结果确实INT类型
  2. 时间格式不对, 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

原因: 在插入数据的时候,插入了表中已有的主键数据,因为主键是唯一的

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值