百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 优雅编程 > 正文

利用Python优雅地操作Oracle数据库

sinye56 2024-10-10 10:59 7 浏览 0 评论

需要源码可以直接联系

方案一:

直接套用脚本,需可以看懂一些脚本逻辑

改代码中 类名为 OracleConnector,它可以同时连接多个 Oracle 数据库,并提供执行增删改查操作的方法。

import cx_Oracle

class OracleConnector:
    def __init__(self, databases):
        self.connections = {}
        for db in databases:
            conn = cx_Oracle.connect(
                user=db['username'],
                password=db['password'],
                dsn=db['dsn'],
                encoding=db.get('encoding', 'UTF-8')
            )
            self.connections[db['name']] = conn

    def execute_query(self, database_name, query, params=None):
        with self.connections[database_name].cursor() as cursor:
            cursor.execute(query, params)
            result = cursor.fetchall()
        return result
    
    def execute_non_query(self, database_name, query, params=None):
        with self.connections[database_name].cursor() as cursor:
            cursor.execute(query, params)
            self.connections[database_name].commit()
            return cursor.rowcount
        
    def execute_query_all(self, databases, query, params=None):
        results = {}
        for db in databases:
            database_name = db['name']
            results[database_name] = self.execute_query(database_name, query, params)
        return results
    
    def execute_non_query_all(self, databases, query, params=None):
        results = {}
        for db in databases:
            database_name = db['name']
            try:
                res = self.execute_non_query(database_name, query, params)
                results[database_name] = res
            except cx_Oracle.DatabaseError as e:
                print(f"Error occurred when running query on {database_name}: {e}")
                self.connections[database_name].rollback()
        return results


以下是代码解释:

import cx_Oracle:导入 cx_Oracle 库,用于与 Oracle 数据库进行连接和交互。

class OracleConnector::定义一个名为 OracleConnector 的类。

def __init__(self, databases)::类的初始化方法,接受一个包含多个数据库信息的列表作为参数。

self.connections = {}:初始化一个字典,用于存储数据库连接。

for db in databases::遍历数据库列表中的每个数据库信息。

conn = cx_Oracle.connect(...):根据数据库信息创建数据库连接对象。user=db['username']:连接数据库的用户名。password=db['password']:连接数据库的密码。dsn=db['dsn']:Oracle 数据库的 DSN(数据源名称)。encoding=db.get('encoding', 'UTF-8'):可选的编码方式,默认为 UTF-8。

self.connections[db['name']] = conn:将数据库连接对象添加到字典中,以数据库名称作为键。

def execute_query(self, database_name, query, params=None)::执行查询语句的方法。database_name:数据库名称。query:要执行的查询语句。params=None:可选的查询参数。

with self.connections[database_name].cursor() as cursor::获取游标对象,用于执行 SQL 语句。

cursor.execute(query, params):执行查询语句。

result = cursor.fetchall():获取查询结果集。

return result:返回查询结果。

def execute_non_query(self, database_name, query, params=None)::执行非查询语句的方法,比如插入、更新和删除操作。

database_name:数据库名称。

query:要执行的非查询语句。

params=None:可选的参数。

with self.connections[database_name].cursor() as cursor::获取游标对象,用于执行 SQL 语句。

cursor.execute(query, params):执行非查询语句,比如插入、更新和删除操作。

self.connections[database_name].commit():提交事务,将修改操作永久保存到数据库中。

return cursor.rowcount:返回受影响的行数,即执行非查询操作后所影响的行数。

def execute_query_all(self, databases, query, params=None)::在多个数据库上执行相同的查询语句,并返回结果。

databases:要执行查询的数据库列表。

query:要执行的查询语句。

params=None:可选的查询参数。

results = {}:初始化一个字典,用于存储查询结果。

for db in databases::遍历数据库列表中的每个数据库。

database_name = db['name']:获取数据库名称。

results[database_name] = self.execute_query(database_name, query, params):执行查询,并将结果存储到字典中。

return results:返回包含查询结果的字典。

def execute_non_query_all(self, databases, query, params=None)::在多个数据库上执行相同的非查询语句,并返回结果。

databases:要执行非查询操作的数据库列表。

query:要执行的非查询语句。

params=None:可选的参数。

results = {}:初始化一个字典,用于存储操作结果。

for db in databases::遍历数据库列表中的每个数据库。

database_name = db['name']:获取数据库名称。

try::捕获可能发生的异常。

res = self.execute_non_query(database_name, query, params):执行非查询操作。

results[database_name] = res:将操作结果存储到字典中。

except cx_Oracle.DatabaseError as e::捕获 Oracle 数据库相关的异常。

print(f"Error occurred when running query on {database_name}: {e}"):打印出错信息。

self.connections[database_name].rollback():执行回滚操作,撤销之前的操作。

return results:返回包含操作结果的字典。

这个封装类使得可以同时连接多个 Oracle 数据库,并在它们上执行增删改查操作。而在执行非查询操作时,如果遇到错误,将会进行回滚操作,保证数据的一致性。


方案二:直接调用封装脚本(写用例,执行脚本即可)

脚本实现封装后,只需要在Oracle.yaml文件中写用例即可,此后执行Oracle.py脚本即实现数据库的增删改查操作

目录介绍:


Oracle.yaml 编写基本数据库信息

Orcale:
  username: user
  password:  pwd
  ip: 127.0.0.1
  port: 1521
  sid: orcl


PublicConfig.py脚本: 配置读取信息,方便调用

import os
from Public_Utils.util_yaml import YamlReader

class YamlPath:
    def __init__(self):
        current = os.path.abspath(__file__)
        self.base_dir = os.path.dirname(os.path.dirname(current))
        self._config_path = self.base_dir + os.sep + "Public_Config\Public_yaml"

    def get_oracle_file(self):
        self._config_file = self._config_path + os.sep + "Oracle.yaml"
        return self._config_file

class ConfigYaml:
    def __init__(self):   #初始yaml读取配置文件
        self.oracle_config = YamlReader(YamlPath().get_oracle_file()).yaml_data()

    def get_oracle_yaml(self):
        return self.oracle_config['Orcale']

if __name__ == '__main__':
    pass


Oracle.py执行脚本

#  coding=utf-8
import cx_Oracle
import os
import json
from Public_Config.PublicConfig import ConfigYaml
os.environ['NLS_LANG'] = 'SIMPLIFIED CHINESE_CHINA.UTF8'

class Oracle:

    def __init__(self):
        user = ConfigYaml().get_oracle_yaml()['username']
        pwd = ConfigYaml().get_oracle_yaml()['password']
        ip = ConfigYaml().get_oracle_yaml()['ip']
        port = ConfigYaml().get_oracle_yaml()['port']
        sid = ConfigYaml().get_oracle_yaml()['sid']
        self.connect = cx_Oracle.connect(str(user) + "/" + str(pwd) + "@" + str(ip) + ":" + str(port) + "/" + str(sid))
        # self.connect = cx_Oracle.connect(f'{user}/{pwd}@{ip}:{port}/{sid}')   # 这里的顺序是 用户名/密码@oracleserver的ip地址/数据库名字
        self.cursor = self.connect.cursor()   # 使用cursor()方法获取操作游标

    def GetData(self,sql):
        self.cursor.execute(sql)
        # 使用Rowfactory更改查询结果,更直观查看数据
        columns = [col[0] for col in self.cursor.description]
        self.cursor.rowfactory = lambda *args: dict(zip(columns, args))
        # fetchall()一次取完所有结果
        # fetchone()一次取一行结果
        data = self.cursor.fetchall()
        return data

    def select(self, sql):   #查询
        list = []
        self.cursor.execute(sql)            # 使用execute方法执行SQL语句
        result = self.cursor.fetchall()     # fetchall()一次取完所有结果,fetchone()一次取一行结果
        col_name = self.cursor.description
        for row in result:
            dict = {}
            for col in range(len(col_name)):
                key = col_name[col][0]
                value = row[col]
                dict[key] = value
            list.append(dict)
        js = json.dumps(list, ensure_ascii=False, indent=2, separators=(',', ':'))
        '''json.dumps() 是把python对象转换成json对象的一个过程,生成的是字符串
           json.dump() 是把python对象转换成json对象生成一个fp的文件流,和文件相关'''
        return js #将结果返回为一个字符串

    def selectlist(self,sql):
        list = []
        self.cursor.execute(sql)
        result = self.cursor.fetchall()
        col_name = self.cursor.description
        for row in result:
            dict = {}
            for col in range(len(col_name)):
                key = col_name[col][0]
                value = row[col]
                dict[key] = value
            list.append(dict)
        return list   #将结果以列表返回

    def disconnect(self):   #未连接
        self.cursor.close()
        self.connect.close()

    def insert(self, sql, list_param):   #插入
        try:
            self.cursor.executemany(sql, list_param)
            self.connect.commit()
            print("插入ok")
        except Exception as e:
            print(e)
        finally:
            self.disconnect()

    def update(self, sql):   #更新
        try:
            self.cursor.execute(sql)
            self.connect.commit()
        except Exception as e:
            print(e)
        finally:
            self.disconnect()

    def delete(self, sql):   #删除
        try:
            self.cursor.execute(sql)
            self.connect.commit()
            print("delete ok")
        except Exception as e:
            print(e)
        finally:
            self.disconnect()

if __name__ == '__main__':
    print(Oracle().select(sql="select * from cifaccount a where a.cif_account ='310400009590' "))
    pass


util_yaml.py

import os
import yaml

class YamlReader:
    #初始化,判断文件是否存在
    def __init__(self,yaml_file):
        if os.path.exists(yaml_file):
            self.yaml_file = yaml_file
        else:
            raise FileNotFoundError("yaml文件不存在")
        self._data = None
        self._data_all = None

    def yaml_data(self):  #yaml文件读取 --单个文档读取
        #第一次调用data,读取yaml文档,如果不是,直接返回之前保存的数据
        if not self._data:
            with open(self.yaml_file,'rb') as f:
                self._data = yaml.safe_load(f)
        return self._data

    def yaml_data_all(self):  #多个文档的读取
        if not self._data_all:
            with open(self.yaml_file,'rb') as f:
                self._data_all = yaml.safe_load_all(f)
        return self._data_all

相关推荐

Linux基础知识之修改root用户密码

现象:Linux修改密码出现:Authenticationtokenmanipulationerror。故障解决办法:进入单用户,执行pwconv,再执行passwdroot。...

Linux如何修改远程访问端口

对于Linux服务器而言,其默认的远程访问端口为22。但是,出于安全方面的考虑,一般都会修改该端口。下面我来简答介绍一下如何修改Linux服务器默认的远程访问端口。对于默认端口而言,其相关的配置位于/...

如何批量更改文件的权限

如果你发觉一个目录结构下的大量文件权限(读、写、可执行)很乱时,可以执行以下两个命令批量修正:批量修改文件夹的权限chmod755-Rdir_name批量修改文件的权限finddir_nam...

CentOS「linux」学习笔记10:修改文件和目录权限

?linux基础操作:主要介绍了修改文件和目录的权限及chown和chgrp高级用法6.chmod修改权限1:字母方式[修改文件或目录的权限]u代表所属者,g代表所属组,o代表其他组的用户,a代表所有...

Linux下更改串口的权限

问题描述我在Ubuntu中使用ArduinoIDE,并且遇到串口问题。它过去一直有效,但由于可能不必要的原因,我觉得有必要将一些文件的所有权从root所有权更改为我的用户所有权。...

Linux chown命令:修改文件和目录的所有者和所属组

chown命令,可以认为是"changeowner"的缩写,主要用于修改文件(或目录)的所有者,除此之外,这个命令也可以修改文件(或目录)的所属组。当只需要修改所有者时,可使用...

chmod修改文件夹及子目录权限的方法

chmod修改文件夹及子目录权限的方法打开终端进入你需要修改的目录然后执行下面这条命令chmod777*-R全部子目录及文件权限改为777查看linux文件的权限:ls-l文件名称查看li...

Android 修改隐藏设置项权限

在Android系统中,修改某些隐藏设置项或权限通常涉及到系统级别的操作,尤其是针对非标准的、未在常规用户界面显示的高级选项。这些隐藏设置往往与隐私保护、安全相关的特殊功能有关,或者涉及开发者选项、权...

完蛋了!我不小心把Linux所有的文件权限修改了!在线等修复!

最近一个客户在群里说他一不小心把某台业务服务器的根目录权限给改了,本来想修改当前目录,结果执行成了根目录。...

linux改变安全性设置-改变所属关系

CentOS7.3学习笔记总结(五十八)-改变安全性设置-改变所属关系在以前的文章里,我介绍过linux文件权限,感兴趣的朋友可以关注我,阅读一下这篇文章。这里我们不在做过的介绍,注重介绍改变文件或者...

Python基础到实战一飞冲天(一)--linux基础(七)修改权限chmod

#07_Python基础到实战一飞冲天(一)--linux基础(七)--修改权限chmod-root-groupadd-groupdel-chgrp-username-passwd...

linux更改用户权限为root权限方法大全

背景在使用linux系统时,经常会遇到需要修改用户权限为root权限。通过修改用户所属群组groupid为root,此操作只能使普通用户实现享有部分root权限,普通用户仍不能像root用户一样享有超...

怎么用ip命令在linux中添加路由表项?

在Linux中添加路由表项,可以使用ip命令的route子命令。添加路由表项的基本语法如下:sudoiprouteadd<network>via<gateway>这...

Linux配置网络

1、网卡名配置相关文件回到顶部网卡名命名规则文件:/etc/udev/rules.d/70-persistent-net.rules#PCIdevice0x8086:0x100f(e1000)...

Linux系列---网络配置文件

1.网卡配置文件在/etc/sysconfig/network-scripts/下:[root@oldboynetwork-scripts]#ls/etc/sysconfig/network-s...

取消回复欢迎 发表评论: