MySQL Connector/Python not closing connection explicitly
我有以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 |
我可以使用
1 2 3 | 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配置上查找什么来避免这些中止连接?
另外,我还经常在错误日志中观察这些消息:
1 2 3 4 | 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和其他配置设置的各种解决方案,但无法使它们中的任何一个工作。
这不是配置问题。完成连接后,应通过显式调用
所以,也许是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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
我重写了上面的课程看起来像这样......
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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) ... |
然后我可以使用
1 2 | with FooData() as obj: obj.etl() |
因此可以正确地消除
Oliver Dain的回答让我走上了正确的道路,解释Python的'__enter __'和'__exit__'对于理解实现我的类的正确方法非常有帮助。