python跨库调用数据库_从不同的python模块调用数据库对象

本文探讨了在Python 2.7中使用MySQLdb与MariaDB交互时,如何正确地在不同模块间共享数据库连接。作者遇到的问题是尝试跨模块插入数据时出现'OperationalError: (1046, 'No database selected')'。解决方案包括改进数据库连接管理,避免全局游标,确保事务处理,并提供更好的异常处理策略。" 113013155,7836804,Java后端面试解析:美团、网易、滴滴面经分享,"['Java', '面试', '架构', '编程语言', '程序人生']
摘要由CSDN通过智能技术生成

我正在将Python 2.7中的MySQLdb模块与MariaDB数据库一起使用。我想知道跨多个模块使用数据库的正确方法。我有一个示例,尝试将另一个函数中的元素插入数据库。我越来越OperationalError: (1046, 'No database selected')

编辑:这里是校正码(1,2)。谢谢。知道我想要这样一个带有依赖注入的工作示例。

这是我要在其中处理数据库的模块。

# test.py

import MySQLdb

import traceback

import test2 as insert_module

from warnings import filterwarnings

# Ignore MySQL `table already exists` warnings

filterwarnings ('ignore', category = MySQLdb.Warning)

# Create database object to keep it open as global variable

class MyDB (object):

connection = None

cursor = None

# Open database connection

def connect (self):

self.connection = MySQLdb.connect ()

self.cursor = self.connection.cursor ()

def execute (self, sql, *args):

try:

self.cursor.execute (sql, *args)

self.connection.commit ()

except MySQLdb.Error, e:

print (traceback.format_exc())

self.connection.rollback ()

def query (self, sql, *args):

try:

self.execute (sql, *args)

# Reopen database connection

except ( AttributeError, MySQLdb.OperationalError ):

self.connect ()

self.execute (sql, *args)

def disconnect (self):

self.connection.close ()

db = MyDB ()

def createDatabase ():

db.query ("CREATE DATABASE IF NOT EXISTS Product")

db.query ("USE Product")

sql = """CREATE TABLE IF NOT EXISTS `ProductColor` (

`ProductID` VARCHAR(20) PRIMARY KEY,

`ColorID` VARCHAR(20)

)"""

db.query (sql)

def insertProductColor (*args):

sql = """INSERT INTO `ProductColor` VALUE (%s, %s)"""

db.query (sql, args)

def main ():

createDatabase ()

insert_module.processListOfProductColors ()

if __name__ == "__main__":

main ()

db.disconnect ()

这是我要从中插入产品的模块。

#test2.py

import test as db_module

def processListOfProductColors ():

db_module.insertProductColor ("cup", "blue")

解决方案

大多无关,但:

# Create database object to keep it open as global variable

class MyDB (object):

connection = None

cursor = None

这些类属性是无用的-将它们定义为实例属性:

def __init__(self):

self.connection = None

self.cursor = None

当我们使用它时:不要对所有查询重复使用相同的游标。否则,当您在遍历第一个查询的结果时尝试执行另一个查询时会遇到麻烦(并且不要谈论多线程...)

# Open database connection

def connect (self):

self.connection = MySQLdb.connect ()

当然,您应该检查是否已经打开了连接,如果可以,请先关闭它,或者只是跳过MySQLdb.connect()呼叫。

同样,对于FWIW,您必须将连接信息(用户名,密码,数据库名称等)传递给MySQLdb.connect()呼叫。您的OperationalError来自未在此处传递数据库名称。

self.cursor = self.connection.cursor ()

cf以上:这只会给您带来麻烦。每次使用一个新的游标,这就是dbapi的预期用途。

def execute (self, sql, *args):

try:

self.cursor.execute (sql, *args)

cf以上

self.connection.commit ()

您应该给调用方一种在每次调用后不提交的方式-他可能希望在单个事务中执行多个语句(实际上这是进行事务的一部分...)

except MySQLdb.Error, e:

你要:

except MySQLdb.Error as e:

print (traceback.format_exc())

设置记录器(python的logging模块)并调用logger.exception(...)。

self.connection.rollback ()

和?假装没关系???您显然想在这里重新引发异常。

def query (self, sql, *args):

try:

self.execute (sql, *args)

您确定要提交读取查询的事务吗?

# Reopen database connection

except ( AttributeError, MySQLdb.OperationalError ):

self.connect ()

self.execute (sql, *args)

错误...如果要延迟处理连接,则您失败了。看看python对计算属性的支持(property等)。

def disconnect (self):

self.connection.close ()

更笼统地说:尝试将连接部分包装在可以(最终懒惰地)处理连接问题的东西中可能是一个好主意(但也不是那么容易...),但是一定要让调用者处理光标并手动交易。这里的一个解决办法是使execute()和query() 上下文管理器是关闭游标并提交(或回滚)事务。还要记住,不良的异常处理比没有异常处理更糟糕。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值