Django ElasticSearch Celery 任务模型调用返回“str”对象不可调用
Posted
技术标签:
【中文标题】Django ElasticSearch Celery 任务模型调用返回“str”对象不可调用【英文标题】:Django ElasticSearch Celery Task Model call returns 'str' object is not callable 【发布时间】:2019-10-27 04:18:42 【问题描述】:遇到了一个奇怪的问题,在其他使用 celery 和 django 的项目中没有发生过。
我正在获取一个 JSON obj,对其进行迭代,并将其放入 django 模型中,但无法创建模型。
tasks.py
from __future__ import absolute_import, unicode_literals
from myapp.celery import app
from django.apps import apps
from datetime import datetime
from zeep import Client, Settings, helpers
from zeep.wsse.username import UsernameToken
from .models import *
import pickle, json, copy
class DateTimeEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return o.isoformat()
return json.JSONEncoder.default(self, o)
@app.task()
def getProjects():
#dumpfile is a pickled zeep obj
dumpfile = open('dump.txt','rb')
getDataObjs = pickle.load(dumpfile)
getDataObjsAsOrderedDict = helpers.serialize_object(getDataObjs)
getDataObjsAsJson = json.loads(json.dumps(getDataObjsAsOrderedDict, cls=DateTimeEncoder))
for project in getDataObjsAsJson:
try:
new_project_project_key = int(copy.deepcopy(project['projectKey']))
print(new_project_project_key)
print(type(new_project_project_key))
print(type(MyDjangoDBModel))
new_project_db_obj,created = MyDjangoDBModel.objects.get_or_create(project_key=new_project_project_key)
print("HIT")
这是日志返回的内容
[2019-06-12 15:08:03,319: WARNING/ForkPoolWorker-4] 10836
[2019-06-12 15:08:03,319: WARNING/ForkPoolWorker-4] <class 'int'>
[2019-06-12 15:08:03,319: WARNING/ForkPoolWorker-4] <class 'django.db.models.base.ModelBase'>
[2019-06-12 15:08:03,321: WARNING/ForkPoolWorker-4] 'str' object is not callable
MyDjangoModel = app.get_model('app name', 'model name') 我也遇到了同样的错误,上面是使用 from .models import * 直接导入的。该副本很可能是不必要的,尽管它是为了解决这个问题。
更新
文档.py
from elasticsearch_dsl.connections import connections
from django_elasticsearch_dsl import DocType, Index
from elasticsearch import Elasticsearch, RequestsHttpConnection
from elasticsearch_dsl import Search
client = Elasticsearch(
['https://user:pass@elasticsearch:9200'],
# turn on SSL
use_ssl=True,
# make sure we verify SSL certificates
verify_certs=True,
# provide a path to CA certs on disk
ca_certs='/usr/src/app/ca.crt',
connection_class=RequestsHttpConnection
)
my_search = Search(using=client)
from .models import MyDjangoModel
# Create a connection to ElasticSearch
connections.create_connection()
myDjangoModel = Index('myDjangoModel')
myDjangoModel.settings(
number_of_shards=1,
number_of_replicas=0
)
@myDjangoModel.doc_type
class siteMyDjangoModelDocument(DocType):
class Meta:
model = MyDjangoModel
fields = ['project_key', 'name', 'description', 'userCreated', 'userModified']
# define simple search here
# Simple search function
def search(title):
query = my_search.query("match", name=title)
response = query.execute()
return response
models.py
from django.db import models
# Create your models here.
class MyDjangoModel(models.Model):
"""Handles x"""
project_key = models.IntegerField(db_index=True)
name = models.TextField(blank=True)
description = models.TextField(blank=True)
userCreated = models.TextField(blank=True)
userModified = models.TextField(blank=True)
根据要求,我在 celery 之外运行了这个,这就是回溯的样子,根本原因看起来是 django_elasticsearch_dsl 库, 我在上面添加了models.py和documents.py。
'str' object is not callable
Traceback (most recent call last):
File "tests.py", line 59, in <module>
new_project_db_obj = GetProjects.objects.create(project_key=new_project_project_key)
File "/usr/local/lib/python3.7/site-packages/django/db/models/manager.py", line 82, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django/db/models/query.py", line 422, in create
obj.save(force_insert=True, using=self.db)
File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 741, in save
force_update=force_update, update_fields=update_fields)
File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 790, in save_base
update_fields=update_fields, raw=raw, using=using,
File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in send
for receiver in self._live_receivers(sender)
File "/usr/local/lib/python3.7/site-packages/django/dispatch/dispatcher.py", line 175, in <listcomp>
for receiver in self._live_receivers(sender)
File "/usr/local/lib/python3.7/site-packages/django_elasticsearch_dsl/signals.py", line 57, in handle_save
registry.update(instance)
File "/usr/local/lib/python3.7/site-packages/django_elasticsearch_dsl/registries.py", line 75, in update
doc().update(instance, **kwargs)
File "/usr/local/lib/python3.7/site-packages/django_elasticsearch_dsl/documents.py", line 231, in update
self._get_actions(object_list, action), **kwargs
File "/usr/local/lib/python3.7/site-packages/django_elasticsearch_dsl/documents.py", line 191, in bulk
return bulk(client=self.connection, actions=actions, **kwargs)
File "/usr/local/lib/python3.7/site-packages/elasticsearch_dsl/document.py", line 269, in _get_connection
return connections.get_connection(using or self._doc_type.using)
File "/usr/local/lib/python3.7/site-packages/elasticsearch_dsl/connections.py", line 91, in get_connection
return self.create_connection(alias, **self._kwargs[alias])
File "/usr/local/lib/python3.7/site-packages/elasticsearch_dsl/connections.py", line 66, in create_connection
conn = self._conns[alias] = Elasticsearch(**kwargs)
File "/usr/local/lib/python3.7/site-packages/elasticsearch/client/__init__.py", line 192, in __init__
self.transport = transport_class(_normalize_hosts(hosts), **kwargs)
File "/usr/local/lib/python3.7/site-packages/elasticsearch/transport.py", line 127, in __init__
self.set_connections(hosts)
File "/usr/local/lib/python3.7/site-packages/elasticsearch/transport.py", line 177, in set_connections
connections = list(zip(connections, hosts))
File "/usr/local/lib/python3.7/site-packages/elasticsearch/transport.py", line 173, in _create_connection
return self.connection_class(**kwargs)
TypeError: 'str' object is not callable
【问题讨论】:
你能手动运行getProjects
,作为一个常规的python方法(不是一个celery任务),然后发布整个回溯吗?
会做并添加信息!
请展示 for 循环的其余部分,尤其是 except 块。
循环的其余部分是我从 dataObj var 加载内容,尽管使用 except 部分,但我正在使用 print(e) 打印异常消息
您使用的Django
、elasticsearch
、elasticsearch-dsl
和django-elasticsearch-dsl
是哪个版本的?
【参考方案1】:
请确保每个包的版本都是正确的,特别是:
Django
elasticsearch
,
elasticsearch-dsl
,
django-elasticsearch-dsl
确保它们之间兼容并受支持,还请记住您正在通过 Python 3.7
运行所有内容
【讨论】:
很抱歉花了这么长时间才接受这个作为答案,确实想添加问题原来是版本控制和错误的 ssl 设置。【参考方案2】:你的字段project_key
是在MyDjangoDBModel
CharField 上吗?
如果project['projectKey']
也是字符串,试试直接放。
MyDjangoDBModel.objects.get_or_create(project_key=project['projectKey'])
让我们看看会不会有什么不同。
【讨论】:
有趣的故事,我之前在 project_key 最初是 CharField 时尝试过上述方法,在尝试解决此问题时,我已将其更改为 IntegerField 尽管仍然遇到相同的错误 嘿,那些不赞成投票的人,请不要,此时任何帮助都是首选以上是关于Django ElasticSearch Celery 任务模型调用返回“str”对象不可调用的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch:如何在 Django 中使用 Elasticsearch
Elasticsearch:如何在 Django 中使用 Elasticsearch
Django + Elasticsearch——搜索精彩的TED演讲
Django + ElasticSearch + Docker - 无论我使用啥主机名,连接超时