python cx_Oracle的基础使用方法(连接和增删改查)


Posted in Python onNovember 19, 2017

问题

使用python操作oracle数据库,获取表的某几个字段作为变量值使用。

使用Popen+sqlplus的方法需要对格式进行控制,通过流获取这几个字段值不简洁(个人观点……)。(优点是能够使用sqlplus的方法直接访问sql文件,不需要考虑打开/关闭连接,并且通过流向文件中写入还挺好用的。不过优点不是这次所关注的)

使用cx-Oracle将查询结果返回为tuple格式,对返回结果的操作简洁,满足需求。(要注意数据库连接创建与关闭、sql的编写、预处理与提交等等,看起来也不简洁(同样个人观点……))

基础方法

数据库连接

1、使用tns串连接

oracle_tns = cx_Oracle.makedsn('XXX.XXX.XXX.XXX', 1521,'oracleName')
connectObj = cx_Oracle.connect('oracleUserName', 'password', oracle_tns)

2、其他简洁方式

db = cx_Oracle.connect('hr', 'hrpwd', 'localhost:1521/XE')
db1 = cx_Oracle.connect('hr/hrpwd@localhost:1521/XE')

数据库断开连接

connectObj.close()

建立游标

cursorObj = connectObj.cursor()

关闭游标

cursorObj.close()

1、单条插入:

sql = "INSERT INTO T_AUTOMONITOR_TMP(point_id) VALUES(:pointId)"
cursorObj.prepare(sql)
rown = cursorObj.execute(None, {'pointId' : pointId})
connectObj.commit()

2、多条插入:

sql = "INSERT INTO T_AUTOMONITOR_TMP(point_id) VALUES(:pointId)"
cursorObj.prepare(sql)
rown = cursorObj.executemany(None, recordList)
connectObj.commit()

sql = "DELETE FROM T_AUTOMONITOR_TMP t WHERE t.point_id = :pointId "
cursorObj.prepare(sql)
rown = cursorObj.execute(None, {'pointId' : pointId})
connectObj.commit()

sql = "UPDATE t_automonitor_other t\
  SET t.active = '2'\
  WHERE t.active = '1'\
  AND t.point_id = :pointId\
  "
cursorObj.prepare(sql)
cursorObj.execute(None, {'pointId' : pointId})
connectObj.commit()

sql = "SELECT t.describ FROM t_automonitor_tmp t WHERE t.point_id = :pointId"
cursorObj.prepare(sql)
cursorObj.execute(None, {'pointId' : pointId})

Tips

  • 增、删、改操作都需要当前连接进行commit()
  • 若使用一个游标cursor进行N次查询,注意若再使用前N-1次查询结果可能会存在异常。要进行多个查询,个人建议使用完cursor后将结果保留再关闭cursor,多次查询重复该操作。
  • 如果不使用prepare,可以直接使用execute,以下查询等价:
r1 = cursor.execute('SELECT * FROM locations WHERE country_id=:1 AND city=:2', ('US', 'Seattle'))
r2 = cursor.execute('SELECT * FROM locations WHERE country_id=:9 AND city=:4', ('US', 'Seattle'))
r3 = cursor.execute('SELECT * FROM locations WHERE country_id=:m AND city=:0', ('US', 'Seattle'))
  • sql语句的语法与数据库有关,不想使用绑定变量,可以拼接sql字符串 (´•༝•`)

简单工具

class baseUtilsX():
 """baseUtils"""
 def __init__(self):
  self.connectObj = ""
  self.connCnt = 0
  self.cursorCnt = 0

 def initOracleConnect(self):
  oracle_tns = cx_Oracle.makedsn('XXX.XXX.XXX.XXX', 1521,'XX')
  if self.connCnt == 0:
   self.connectObj = cx_Oracle.connect('oracleUserName', 'password', oracle_tns)
   self.connCnt += 1

 def getOracleConnect(self):
  self.initOracleConnect()
  return self.connectObj
 
 def closeOracleConnect(self, connectObj):
  connectObj.close()
  self.connCnt -= 1

 def getOracleCursor(self):
  self.initOracleConnect()
  self.cursorCnt += 1
  return self.connectObj.cursor()

 def closeOracleCursor(self, cursorObj):
  cursorObj.close()
  self.cursorCnt -= 1
  if self.cursorCnt == 0:
   print "will close conn"
   self.closeOracleConnect(self.connectObj)

 def selectFromDbTable(self, sql, argsDict):
  # 将查询结果由tuple转为list
  queryAnsList = []
  selectCursor = self.getOracleCursor()
  selectCursor.prepare(sql)
  queryAns = selectCursor.execute(None, argsDict)
  for ansItem in queryAns:
   queryAnsList.append(list(ansItem))

  self.closeOracleCursor(selectCursor)
  return queryAnsList

python 连接 Oracle 乱码问题(cx_Oracle)

用python连接Oracle是总是乱码,最后发现时oracle客户端的字符编码设置不对。

编写的python脚本中需要加入如下几句:

import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'

这样可以保证select出来的中文显示没有问题。

要能够正常的insert和update中文,还需要指定python源文件的字符集密码和oracle一致。

# -*- coding: utf-8 -*-

例子:

# -*- coding: utf-8 -*-

import os
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8' #或者os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.AL32UTF8'

 

import cx_Oracle
db = cx_Oracle.connect(username/passwd@host:port/sevicename)
cursor = db.cursor()
#其他操作

db.commit()
db.close()

参考:

客户端的NLS_LANG设置及编码转换

      ①在Oracle客户端向服务器端提交SQL语句时,Oracle客户端根据NLS_LANG和数据库字符集,对从应用程序接传送过来的字符串编码进行转换处理。如果NLS_LANG与数据库字符集相同,不作转换,否则要转换成数据库字符集并传送到服务器。服务器在接收到字符串编码之后,对于普通的CHAR或VARCHAR2类型,直接存储;对于NCHAR或NVARCHAR2类型,服务器端将其转换为国家字符集再存储。

      ①在Oracle客户端向服务器端提交SQL语句时,Oracle客户端根据NLS_LANG和数据库字符集,对从应用程序接传送过来的字符串编码进行转换处理。如果NLS_LANG与数据库字符集相同,不作转换,否则要转换成数据库字符集并传送到服务器。服务器在接收到字符串编码之后,对于普通的CHAR或VARCHAR2类型,直接存储;对于NCHAR或NVARCHAR2类型,服务器端将其转换为国家字符集再存储。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

参考文章

精通 Oracle+Python,第 1 部分:查询最佳应践

Python 相关文章推荐
python类定义的讲解
Nov 01 Python
python端口扫描系统实现方法
Nov 19 Python
用Python编写一个简单的Lisp解释器的教程
Apr 03 Python
python通过socket查询whois的方法
Jul 18 Python
python常见排序算法基础教程
Apr 13 Python
Python实现将数据写入netCDF4中的方法示例
Aug 30 Python
python3下载抖音视频的完整代码
Jun 05 Python
python开启debug模式的方法
Jun 27 Python
Python从入门到精通之环境搭建教程图解
Sep 26 Python
sklearn-SVC实现与类参数详解
Dec 10 Python
Python的对象传递与Copy函数使用详解
Dec 26 Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
Jul 23 Python
Python实现mysql数据库更新表数据接口的功能
Nov 19 #Python
python中urlparse模块介绍与使用示例
Nov 19 #Python
Python Flask-web表单使用详解
Nov 18 #Python
python+selenium实现京东自动登录及秒杀功能
Nov 18 #Python
深入理解Python单元测试unittest的使用示例
Nov 18 #Python
Python及PyCharm下载与安装教程
Nov 18 #Python
Python实现读取json文件到excel表
Nov 18 #Python
You might like
PHP文本操作类
2006/11/25 PHP
php Memcache 中实现消息队列
2009/11/24 PHP
初步介绍PHP扩展开发经验分享
2012/09/06 PHP
修改apache配置文件去除thinkphp url中的index.php
2014/01/17 PHP
PHP使用mysql_fetch_row查询获得数据行列表的方法
2015/03/18 PHP
Laravel使用swoole实现websocket主动消息推送的方法介绍
2019/10/20 PHP
jQuery 入门级学习笔记及源码
2010/01/22 Javascript
javascript 函数速查表
2010/02/07 Javascript
javascript下4个跨浏览器必备的函数
2010/03/07 Javascript
JavaScript中判断整字类型最简洁的实现方法
2014/11/08 Javascript
js实现交换运动效果的方法
2015/04/10 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
浅谈JavaScript的Polymer框架中的behaviors对象
2015/07/29 Javascript
JS组件Bootstrap导航条使用方法详解
2016/04/29 Javascript
解析JavaScript模仿块级作用域
2016/12/29 Javascript
vue loadmore 组件滑动加载更多源码解析
2017/07/19 Javascript
JS异步函数队列功能实例分析
2017/11/28 Javascript
js 根据对象数组中的属性进行排序实现代码
2019/09/12 Javascript
解决angular 使用原生拖拽页面卡顿及表单控件输入延迟问题
2020/04/21 Javascript
Js on及addEventListener原理用法区别解析
2020/07/11 Javascript
关于angular引入ng-zorro的问题浅析
2020/09/09 Javascript
[46:20]CHAOS vs Alliacne 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python定时执行指定函数的方法
2015/05/27 Python
Python更新数据库脚本两种方法及对比介绍
2017/07/27 Python
Python实现模拟分割大文件及多线程处理的方法
2017/10/10 Python
pandas求两个表格不相交的集合方法
2018/12/08 Python
python3.6生成器yield用法实例分析
2019/08/23 Python
python安装本地whl的实例步骤
2019/10/12 Python
怎么解决pycharm license Acti的方法
2020/10/28 Python
去加拿大的旅行和假期:Canadian Affair
2016/10/25 全球购物
中国医药集团国药在线:国药网
2017/02/06 全球购物
2014年最新离婚协议书范本
2014/10/11 职场文书
2015年节能降耗工作总结
2015/05/22 职场文书
go mod 安装依赖 unkown revision问题的解决方案
2021/05/06 Golang
整理Python中常用的conda命令操作
2021/06/15 Python
python机器学习Github已达8.9Kstars模型解释器LIME
2021/11/23 Python