python cx_Oracle的基础使用方法(连接和增删改查)
问题
使用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="INSERTINTOT_AUTOMONITOR_TMP(point_id)VALUES(:pointId)" cursorObj.prepare(sql) rown=cursorObj.execute(None,{'pointId':pointId}) connectObj.commit()
2、多条插入:
sql="INSERTINTOT_AUTOMONITOR_TMP(point_id)VALUES(:pointId)" cursorObj.prepare(sql) rown=cursorObj.executemany(None,recordList) connectObj.commit()
删
sql="DELETEFROMT_AUTOMONITOR_TMPtWHEREt.point_id=:pointId" cursorObj.prepare(sql) rown=cursorObj.execute(None,{'pointId':pointId}) connectObj.commit()
改
sql="UPDATEt_automonitor_othert\ SETt.active='2'\ WHEREt.active='1'\ ANDt.point_id=:pointId\ " cursorObj.prepare(sql) cursorObj.execute(None,{'pointId':pointId}) connectObj.commit()
查
sql="SELECTt.describFROMt_automonitor_tmptWHEREt.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*FROMlocationsWHEREcountry_id=:1ANDcity=:2',('US','Seattle')) r2=cursor.execute('SELECT*FROMlocationsWHEREcountry_id=:9ANDcity=:4',('US','Seattle')) r3=cursor.execute('SELECT*FROMlocationsWHEREcountry_id=:mANDcity=:0',('US','Seattle'))
- sql语句的语法与数据库有关,不想使用绑定变量,可以拼接sql字符串(´•༝•`)
简单工具
classbaseUtilsX(): """baseUtils""" def__init__(self): self.connectObj="" self.connCnt=0 self.cursorCnt=0 definitOracleConnect(self): oracle_tns=cx_Oracle.makedsn('XXX.XXX.XXX.XXX',1521,'XX') ifself.connCnt==0: self.connectObj=cx_Oracle.connect('oracleUserName','password',oracle_tns) self.connCnt+=1 defgetOracleConnect(self): self.initOracleConnect() returnself.connectObj defcloseOracleConnect(self,connectObj): connectObj.close() self.connCnt-=1 defgetOracleCursor(self): self.initOracleConnect() self.cursorCnt+=1 returnself.connectObj.cursor() defcloseOracleCursor(self,cursorObj): cursorObj.close() self.cursorCnt-=1 ifself.cursorCnt==0: print"willcloseconn" self.closeOracleConnect(self.connectObj) defselectFromDbTable(self,sql,argsDict): #将查询结果由tuple转为list queryAnsList=[] selectCursor=self.getOracleCursor() selectCursor.prepare(sql) queryAns=selectCursor.execute(None,argsDict) foransIteminqueryAns: queryAnsList.append(list(ansItem)) self.closeOracleCursor(selectCursor) returnqueryAnsList
python连接Oracle乱码问题(cx_Oracle)
用python连接Oracle是总是乱码,最后发现时oracle客户端的字符编码设置不对。
编写的python脚本中需要加入如下几句:
importos os.environ['NLS_LANG']='SIMPLIFIEDCHINESE_CHINA.UTF8'
这样可以保证select出来的中文显示没有问题。
要能够正常的insert和update中文,还需要指定python源文件的字符集密码和oracle一致。
#-*-coding:utf-8-*-
例子:
#-*-coding:utf-8-*- importos os.environ['NLS_LANG']='SIMPLIFIEDCHINESE_CHINA.UTF8'#或者os.environ['NLS_LANG']='AMERICAN_AMERICA.AL32UTF8' importcx_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部分:查询最佳应践