abo*_*nov 3 python django postgresql multiprocessing jupyter-notebook
我使用 Jupyter Notebook 来处理我存储在 django/postgres 中的数据。我以这种方式初始化我的项目:
sys.path.append('/srv/gr/prg')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'prg.settings')
if 'setup' in dir(django):
django.setup()
Run Code Online (Sandbox Code Playgroud)
有许多更新数据的独立进程,我想多线程处理它以加快进程。当我在单个线程中进行更新或使用时,一切正常sqlite.
def extract_org_description(id):
o = models.Organization.objects.get(pk=id)
logging.info("Looking for description for %s" % o.symbol)
try:
content = open('/srv/data/%s.html' % o.symbol)
except FileNotFoundError:
logging.error("HTML file not found for %s" % o.symbol)
return
doc = BeautifulSoup(content, 'html.parser')
desc = doc.select("#cr_description_mod > div.cr_expandBox > div.cr_description_full.cr_expand")
if not desc or not desc[0]:
logging.info("Cannot not find description for %s" % o.symbol)
return
o.description = desc[0].text
o.save(update_fields=['description'])
logging.info("Description for %s found" % o.symbol)
return("done %s" % id)
Run Code Online (Sandbox Code Playgroud)
这将不起作用:
p = Pool(2)
result = p.map(extract_org_description, orgs)
print(result)
Run Code Online (Sandbox Code Playgroud)
大多数情况下,它会挂起直到我中断它,没有任何特定错误,有时 postgres 会出现“已经有一个事务在进行中”,有时我会看到“没有结果可获取”错误。玩池大小我可以让它工作一两次,但很难诊断到底是什么问题。
我尝试将策略更改为选择对象并将它们映射到 extract_org_description将对象作为参数的(不同于基于键的选择),但这并没有更好的效果。
我唯一的想法是,当 django 尝试自动提交时,所有单独的更新,包括其他线程中发生的更新,都在同一事务范围内,这导致了问题。但我不明白如何在 Django 中解决这个问题。
您的问题包括术语multiprocessing和multithread,但重要的是要了解这些是实现并发的不同方式。
Django 内置了对多线程的支持,并且会为每个线程创建一个新的数据库连接。如果您从多处理切换到多线程,您的问题应该得到解决。
在多处理中,整个进程被分叉,新进程将与旧进程具有相同的数据库连接。这会导致您所看到的问题,例如,当另一个进程已在同一数据库连接上打开一个新事务时,您尝试打开一个新事务。
如果您确实需要多处理而不是多线程,则可能有解决方案。例如,这个答案建议简单地关闭数据库连接,强制 Django 创建新的连接。
| 归档时间: |
|
| 查看次数: |
1270 次 |
| 最近记录: |