python - 分配可挑选的全局变量
问题描述
如果这是一个容易解决的问题,我很抱歉,我已经尝试过搜索但无法找到解决方案。我来自 PHP,所以也许我想要实现的目标是不可能的,或者它需要在 python 中以不同的方式完成。
好的,所以我有一个名为的类database.py
,它解析配置文件,并根据我使用的“数据库”类型返回一个对象sqlite
或mysql
数据库.py
import mysql.connector
from mysql.connector import Error
from mysql.connector import pooling
class Database:
# Connect to the database
@staticmethod
def connect():
if Config().type() == 'mysql':
return mysql.connector.pooling.MySQLConnectionPool(**Config().mysql())
elif Config().type() == 'sqlite':
return sqlite3.connect("%s.sqlite" % Config().sqlite())
所以,正如你所看到的,我正在返回我正在使用的数据库的一个对象,对于这个例子,假设Config().type() == 'mysql'
是真的,我们正在使用mysql
,而 theConfig().mysql()
只是一个像这样的字典:
{
'pool_name': "indexit",
'pool_size': config['DATABASE']['mysql']['pool_size'],
'pool_reset_session': True,
'user': config['DATABASE']['mysql']['user'],
'password': config['DATABASE']['mysql']['password'],
'host': config['DATABASE']['mysql']['host'],
'database': config['DATABASE']['mysql']['database'],
'auth_plugin': 'mysql_native_password',
'charset': 'utf8',
'use_unicode': True
}
在我的主要 python 文件中,我试图将 分配Database.connect()
给一个变量,然后在我的线程函数中使用它并从对象中获取 mysql 池:
from multiprocessing import Pool
from core.database import Database
class Indexit:
# MyProgram constructor
def __init__(self):
# 1 connection for threads
self.database = Database.connect()
# Thread to run
def run(self, id):
# return the id
print(id)
# Get the database pool
print(self.database.get_connection())
# Do the threads
def main(self):
# Pool connections
with Pool(processes=5) as pool:
pool.map(self.run, range(10000000))
Indexit().main()
但我的代码返回错误:(您可以在此处查看完整代码:https ://github.com/filter/indexit )
Traceback (most recent call last):
File "indexit.py", line 75, in <module>
Indexit().main()
File "indexit.py", line 68, in main
pool.map(self.run, range(10000000))
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 268, in map
return self._map_async(func, iterable, mapstar, chunksize).get()
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 657, in get
raise self._value
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/pool.py", line 431, in _handle_tasks
put(task)
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/connection.py", line 206, in send
self._send_bytes(_ForkingPickler.dumps(obj))
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/multiprocessing/reduction.py", line 51, in dumps
cls(buf, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects
所以,我的问题是,我怎样才能使用全局连接,然后使用我的线程函数来获得自己的池工作者?
解决方案
显然,在MySQLConnectionPool
内部使用线程。当您调用map
a 的方法时multiprocessing.Pool
,它会尝试发送运行给定函数所需的所有内容。在这种情况下包括数据库连接池。
当一个新进程被创建时,它只有一个线程。因此,尝试将与线程相关的东西(如锁)发送给子进程是没有意义的。锁拥有的任何数据在子进程中都将毫无意义。因此错误。
您可能应该在池工作者或Pool
.
推荐阅读
- java - 当我们从 UDP 服务器接收数据包时,为什么我们必须在单独的线程中接收它们?
- mysql - 分组中两行之间的SQL差异
- unit-testing - .net Core 3.1 控制器级别的单元测试授权角色
- google-apps-script - 带有 Google App Script 的 Google Sheets:如何在返回最终结果之前向单元格写入“状态”消息?
- javascript - 你能定义 CSS 变换比例的最大宽度/高度吗?
- git - 如何在 Github 的一个分支上继续工作并进行新的 PR
- javascript - 提交在没有按钮的多个输入的表单中不起作用
- python - 使用 python 消费流视频
- java - 如何将私钥从服务器传送到客户端安全?[爪哇]
- android - 我想在 Kotlin 中自定义新按钮时遇到问题