【Python】cx_Oracle 模块 _ 连接Oracle数据库
连接并登陆数据库
# 导入cx_oracle import cx_oracle as oracle
# 连接并登陆数据库 入参: user password ip地址与实例 db = oracle.connect(username, password, ip:port/example)
# 使用tns串连接 oracle_tns = cx_Oracle.makedsn('XXX.XXX.XXX', 1521,'oracleName') db = oracle.connect(username,pass,oracle_tns)
# 简洁连接 db = oracle.connect(username/password@ip:port/example)
创建游标对象
# 创建游标对象 cu = db.cursor()
执行sql语句
sql_statement = f"select * from tablename where 条件" # sql语句 cu.execute(sql_statement ) # 执行sql one_result = cu.fetchone() # 得到单行数据 all_result = cu.fetchall() # 得到全部数据
查询结果显示列名
# 查询结果仅显示3行 numline = 3 sql_statement = f" select * from tablename where rownum <={numline} "
# 将查询数据与表列名组成元组 for i in result: list_list = list(i) des = cursor.description # 获取表详情 t = ",".join([item[0] for item in des]) table_head = t.split(',') # # 查询表列名 用,分割 dict_result = dict(zip(table_head, list_list)) # 打包为元组的列表 在转换为字典 list_result.append(dict_result) # 将字典添加到list_result中
关闭数据库
- 增、删、改操作都需要当前连接进行提交事务后再,关闭游标及数据库连接
# 提交事务 conn.commit() #关闭游标 cu.close() #关闭连接 conn.close()
# coding:utf-8 import cx_Oracle as oracle from loguru import logger as logs class oracle_tools: """oracle 数据库操作工具,请确保sql语句准确""" def __init__(self, env, dbName='project'): """ 打开数据库 :param env: 测试环境 sit/uat/dev :param dbName: 数据库名称 """ self.env = env self.dbName = dbName try: # 获取数据库参数 conf = config.get("db_conn_{}".format(self.env), self.dbName) # 连接登录数据库 self.conn = oracle.connect(conf) # 创建游标对象 self.cu = self.conn.cursor() except Exception as e: E = '连接数据库异常 ' + str(e) # 返回错误代码1和失败原因 logs.error(E) def __del__(self): """对象资源被释放时触发,在对象即将被删除时的最后操作""" # self.cu.close() # 关闭游标 # self.conn.close() # 关闭数据库连接 logs.debug("Oracle> 数据库操作完成") def __select_db(self, sql): """私有属性 查询""" # 使用 execute() 执行sql self.cu.execute(sql) # 使用 fetchall() 获取查询结果 result = self.cu.fetchall() # 将查询数据拼接为字典 list_result = [] for i in result: list1 = list(i) des = self.cu.description # 获取表详情 # logger.debug("表的描述:", des) t = ",".join([item[0] for item in des]) # 查询表列名 用,分割 plan_head = t.split(',') # 打包为元组的列表 在转换为字典 dict1 = dict(zip(plan_head, list1)) # 将字典添加到list_result中 list_result.append(dict1) self.cu.close() # 关闭游标 self.conn.close() # 关闭数据库连接 logs.debug("Oracle> sql执行完成 ") try: if len(result) > 0: # logs.info(">>> 查询成功 <<<") return result[0], list_result except Exception: return 'NULL', ['Null'] def __execute_db(self, sql): """私有属性,创建/更新/插入/删除""" try: # 使用 execute() 执行sql self.cu.execute(sql) # 提交事务 self.conn.commit() # logs.info(">>> 执行成功 <<<") except Exception as e: logs.error(f"操作出现错误:{e}") # 回滚所有更改 self.conn.rollback() finally: self.cu.close() # 关闭游标 self.conn.close() # 关闭数据库连接 def db_exec_command(self, sql): """执行sql命令,特别提示,select 语句禁止使用 update""" sql_data = f'{sql}'.upper() try: # 判断sql语句类型, if sql_data.startswith('SELECT'): # logs.debug("正在执行 查询 操作:\n\t\t 语句:%s" % sql_data) self.cu.execute(sql) result = self.cu.fetchall() # 得到全部行数据 # 判断 如果是查询语句, 将查询数据与表列表组成元组 list_result = [] for i in result: list1 = list(i) des = self.cu.description # 获取表详情 # logger.debug("表的描述:", des) t = ",".join([item[0] for item in des]) # 查询表列名 用,分割 plan_head = t.split(',') # 打包为元组的列表 在转换为字典 dict1 = dict(zip(plan_head, list1)) # 将字典添加到list_result中 list_result.append(dict1) else: # logs.debug("正在执行 创建/更新/插入/删除 操作:\n\t\t 语句:%s" % sql_data) self.cu.execute(sql) self.conn.commit() # 插入语句后需要提交数据 except Exception as e: # 当sql不是查询语句时,滚所有更改 if not sql_data.startswith('SELECT'): self.conn.rollback() logs.error("异常原因:%s" % e) finally: self.cu.close() # 关闭游标 self.conn.close() # 关闭数据库连接 try: if len(result) > 0: return result[0], list_result except Exception: return 'NULL', ['Null'] if __name__ == "__main__": env = 'sit' sql = f"select * from sys_global" re = oracle_tools(env, "db").db_exec_command(sql) logs.debug(re)
拓展
cx_oracle 安装失败,解决办法:https://www.cnblogs.com/phoenixy/p/15205039.html
预处理语句 [待补充]
cu.prepare(sql)
插入语句可以使用多条插入
executemany(None, recordList)
如果python连接cx_oracle 时出现乱码
import os os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'
-------------------------------------------------------------------------------------
如果万事开头难 那请结局一定圆满 @ Phoenixy
-------------------------------------------------------------------------------------