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实现自动登录人人网并访问最近来访者实例
Sep 26 Python
让 python 命令行也可以自动补全
Nov 30 Python
python3实现短网址和数字相互转换的方法
Apr 28 Python
详解Python中的日志模块logging
Jun 19 Python
Python编程实现两个文件夹里文件的对比功能示例【包含内容的对比】
Jun 20 Python
TensorFlow实现随机训练和批量训练的方法
Apr 28 Python
python用户评论标签匹配的解决方法
May 31 Python
Python使用pylab库实现绘制直方图功能示例
Jun 01 Python
使用python爬虫获取黄金价格的核心代码
Jun 13 Python
解决python打不开文件(文件不存在)的问题
Feb 18 Python
PyTorch里面的torch.nn.Parameter()详解
Jan 03 Python
Python爬取新型冠状病毒“谣言”新闻进行数据分析
Feb 16 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 全局变量范围分析
2009/08/07 PHP
php 获取本机外网/公网IP的代码
2010/05/09 PHP
解析php多线程下载远程多个文件
2013/06/25 PHP
PHP使用mysqli操作MySQL数据库的简单方法
2017/02/04 PHP
几个高效,简洁的字符处理函数
2007/04/12 Javascript
JS学习之一个简易的日历控件
2010/03/24 Javascript
jquery 事件对象属性小结
2010/04/27 Javascript
flexigrid 类似ext grid的JS表格代码
2010/07/17 Javascript
为你的网站增加亮点的9款jQuery插件推荐
2011/05/03 Javascript
node.js中的fs.readFileSync方法使用说明
2014/12/15 Javascript
jQuery实现图片与文字描述左右滑动自动切换的方法
2015/07/27 Javascript
Bootstrap每天必学之下拉菜单
2015/11/25 Javascript
jQuery ajax全局函数处理session过期后的ajax跳转问题
2016/06/03 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
2016/06/23 Javascript
bootstrap flask登录页面编写实例
2016/11/01 Javascript
利用js编写网页进度条效果
2017/10/08 Javascript
jquery+ajaxform+springboot控件实现数据更新功能
2018/01/22 jQuery
微信小程序全局变量GLOBALDATA的定义和调用过程解析
2019/09/23 Javascript
vue element 关闭当前tab 跳转到上一路由操作
2020/07/22 Javascript
vue自定义树状结构图的实现方法
2020/10/18 Javascript
Nuxt的动态路由和参数校验操作
2020/11/09 Javascript
[51:44]2018DOTA2亚洲邀请赛 4.3 突围赛 Optic vs iG 第二场
2018/04/04 DOTA
[00:17]DOTA2荣耀之路5:It’s a disastah!
2018/05/28 DOTA
[48:37]EG vs OG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
Python的Django中将文件上传至七牛云存储的代码分享
2016/06/03 Python
Python读取系统文件夹内所有文件并统计数量的方法
2018/10/23 Python
keras实现VGG16 CIFAR10数据集方式
2020/07/07 Python
python批量提取图片信息并保存的实现
2021/02/05 Python
HTML5标签小集
2011/08/02 HTML / CSS
跨域修改iframe页面内容详解
2019/10/31 HTML / CSS
大学生求职简历的自我评价范文
2013/10/12 职场文书
计算机网络专业求职信
2014/06/05 职场文书
运动会跳远广播稿5篇
2014/09/17 职场文书
领导班子对照检查材料
2014/09/22 职场文书
商铺租房协议书范本
2014/12/04 职场文书
关于教师节的广播稿
2015/08/19 职场文书