python - 这是pythonic,即用户上下文管理器的正确方法吗
问题描述
我们有一些代码可以创建到 Oracle 数据库的 SDE 连接。我想创建一个包装类,使连接更易于管理。我尝试这样做是pythonic吗?
通常在我们的 Python 代码中,我们希望在同一个脚本中以几种不同的方式连接到同一个数据库。例如:
- 具有数据库身份验证 (DBA) 用户“A”和默认 SDE 版本的 Esri SDE
- 具有数据库身份验证用户“B”和 SDE 版本“某物”的 Esri SDE
- 具有操作系统身份验证 (OSA) 和 SDE 版本的 Esri SDE
- 使用 cx_Oracle 作为用户“C”的 Oracle 连接
现在我们有一个本土网站包,可以为我们完成大部分工作。但它有两个我遇到的问题:
- 这有点低效。例如,每次需要 SDE DBA 连接时,我都必须将所有信息传递给函数:数据库、连接文件的路径和用户(如果是 DBA 连接)。如果我有一个可以知道数据库和路径信息的类,那就太酷了。然后我可以告诉它我需要什么类型的连接,SDE 或 Oracle 以及用户/DBA 或 OAS 信息。
- 当前代码本身并不能很好地清理。如果由于某种原因失败(或者开发人员忘记调用清理函数),连接将被孤立并随着时间的推移而建立。所以,也许我们应该使用 with 语句来确保东西被清理干净。
import security
from _ceaconnection import createConnection
from _ceaconnection import deleteConnection
import cx_Oracle
from contextlib import contextmanager
class ConnectionHelper:
def __init__(self, database):
self.database = database
self.temp_path = security.tmpPath
@contextmanager
def sde_dba_connection(self, user, version=None):
"""
Create dba sde connection
:param version: sde version
:param user: sde user (schema)
:return: sde connection
"""
connection = None
try:
password = security.get_password(self.database, user.lower())
credentials = dict(server=self.database, user=user, password=password)
connection = createConnection(credentials, self.temp_path, version=version)
yield connection
finally:
if connection is not None:
deleteConnection(connection)
@contextmanager
def sde_osa_connection(self, version=None):
"""
Create osa sde connection
:param version: sde version
:return: sde connection
"""
connection = None
try:
connection = createConnection("OS", self.temp_path, server=self.database, version=version)
yield connection
finally:
if connection is not None:
deleteConnection(connection)
@contextmanager
def oracle_connection_with(self, user):
"""
create cx_oracle connection
:param user: oracle user
:return: oracle connection
"""
password = security.get_password(self.database, user.lower())
with cx_Oracle.connect("{u}/{p}@{db}".format(u=user, p=password, db=self.database)) as connection:
yield connection
此代码在调用时似乎按预期工作:
connection_helper = ceaarcpy.ConnectionHelper('database')
with connection_helper.sde_dba_connection('sde') as conn:
# do some stuff
解决方案
推荐阅读
- string - 来自字符串的 Delphi Hash - 小菜一碟?
- pine-script - 一开始就声明变量
- javascript - 通过 React 功能组件将功能从父级传递给子级
- python - 如何将多个 .npy 文件加载到单个 numpy 数组中
- django - ModelForm 没有将任何数据保存到数据库 - Django
- zsh - zsh 参数扩展,过滤掉与模式匹配的数组元素
- android - Flutter 轻松加载,如何编辑它的文字样式(下划线、字体系列、大小)?
- git - 将功能分支与开发分支同步
- swift - 尝试拨打号码时Swift NSOSStatusErrorDomain
- c++ - 不能为类成员调用函数