python mysql connection close,MySQL Connector / Python未明确关闭连接

毛越
2023-12-01

我有以下内容:

class FooData(object):

def __init__(self):

...

try:

self.my_cnf = os.environ['HOME'] + '/.my.cnf'

self.my_cxn = mysql.connector.connect(option_files=self.my_cnf)

self.cursor = self.my_cxn.cursor(dictionary=True)

except mysql.connector.Error as err:

if err.errno == 2003:

self.my_cnf = None

self.my_cxn = None

self.cursor = None

我可以使用my_cxn和cursor而没有任何明显的失败。 我从未明确终止连接,并在我的mysql错误日志中观察到以下消息,但...

2017-01-08T15:16:09.355190Z 132 [Note] Aborted connection 132 to db:

'mydatabase' user: 'myusername' host: 'localhost'

(Got an error reading communication packets)

我是以错误的方式来做这件事的吗? 每次我需要运行查询时,初始化连接器和光标会更有效吗?

我需要在mysql配置上查找什么来避免这些中止连接?

另外,我还经常在错误日志中观察这些消息:

2017-01-06T15:28:45.203067Z 0 [Warning] Changed limits: max_open_files: 1024

(requested 5000)

2017-01-06T15:28:45.205191Z 0 [Warning] Changed limits: table_open_cache: 431

(requested 2000)

它与上述有关吗? 它是什么意思,我该如何解决?

我尝试了涉及/lib/systemd/system/mysql.service.d/limits.conf和其他配置设置的各种解决方案,但无法使它们中的任何一个工作。

这不是配置问题。完成连接后,应通过显式调用close来关闭它。通常最好的做法是长时间保持连接,因为创建连接需要时间。从你的代码片段中无法判断哪个是关闭它的最佳位置 - 只要你"完成"它就可以了;也许在__main__方法的最后。同样,完成后应该显式关闭游标。通常,这发生在每次查询之后。

所以,也许是这样的:

class FooData(object):

def __init__(self):

...

try:

self.my_cnf = os.environ['HOME'] + '/.my.cnf'

self.my_cxn = mysql.connector.connect(option_files=self.my_cnf)

def execute_some_query(self, query_info):

"""Runs a single query. Thus it creates a cursor to run the

query and closes it when it's done."""

# Note that cursor is not a member variable as it's only for the

# life of this one query

cursor = self.my_cxn.cursor(dictionary=True)

cursor.execute(...)

# All done, close the cursor

cursor.close()

def close():

"""Users of this class should **always** call close when they are

done with this class so it can clean up the DB connection."""

self.my_cxn.close()

您还可以查看Python with语句,以确保始终清理所有内容。

谢谢您的意见。 它澄清说我错误地从不调用cursor.close()并且还需要显式调用my_cxn.close()。 有没有一种很好的方法可以将mysql.connector连接合并到python类中,这样就不会创建与服务器的不必要数量的连接,并且负责任地关闭连接而不需要明确? 使用__enter__和__exit__是一种考虑在类中实现mysql.connector并确保与with一起使用时正确清理的好方法吗?

@Vishal我认为没有一个最好的解决方案。 这取决于你的课程如何使用。 经验法则是创建尽可能少的连接,但是在完成后始终关闭它们。 因此,如何使用您的课程将决定最佳方法。 而且,这个经验法则有例外。

我重写了上面的课程看起来像这样......

class FooData(object):

def __init__(self):

self.myconfig = {

'option_files': os.environ['HOME'] + '/.my.cnf',

'database': 'nsdata'

}

self.mysqlcxn = None

def __enter__(self):

try:

self.mysqlcxn = mysql.connector.connect(**self.myconfig)

except mysql.connector.Error as err:

if err.errno == 2003:

self.mysqlcxn = None

return self

def __exit__(self, exc_type, exc_value, traceback):

if self.mysqlcxn is not None and self.mysqlcxn.is_connected():

self.mysqlcxn.close()

def etl(self)

...

然后我可以使用with ... as并确保我正确清理。

with FooData() as obj:

obj.etl()

因此可以正确地消除Aborted connection消息。

Oliver Dain的回答让我走上了正确的道路,解释Python的'__enter __'和'__exit__'对于理解实现我的类的正确方法非常有帮助。

 类似资料: