gpt4 book ai didi

python - 从不同的Python模块调用数据库对象

转载 作者:行者123 更新时间:2023-11-29 10:32:41 25 4
gpt4 key购买 nike

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

编辑:这是更正后的代码( 12 )。谢谢。我知道我想要一个像这样的带有依赖注入(inject)的工作示例。

这是我想要处理数据库的模块。

# 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() 调用。您的操作错误来自于此处未传递数据库名称。

        self.cursor = self.connection.cursor ()

参见上面:这只会给你带来麻烦。每次使用新的游标,这就是 dbapi 的预期用途。

    def  execute (self, sql, *args):
try:
self.cursor.execute (sql, *args)

参见上文

            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() context managers关闭游标并提交(或回滚)事务。还要记住,糟糕的异常处理比没有异常处理更糟糕......

关于python - 从不同的Python模块调用数据库对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47095206/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com