Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 芹菜腌制不好与卡桑德拉司机,可以';我想不出根本原因_Python_Cassandra_Celery_Pickle - Fatal编程技术网

Python 芹菜腌制不好与卡桑德拉司机,可以';我想不出根本原因

Python 芹菜腌制不好与卡桑德拉司机,可以';我想不出根本原因,python,cassandra,celery,pickle,Python,Cassandra,Celery,Pickle,我正在经历一些我不能完全理解的行为。我使用Cassandra存储消息对象,使用芹菜异步拉入和推入数据库。除了一个芹菜任务外,一切都很好;使用相同代码/类的其他任务也可以工作。下面是代码逻辑的粗略分解: db_manager = DBManager() class User(object): def __init__(self, user_id): ... normal init stuff ... self.loader() @run_asyn

我正在经历一些我不能完全理解的行为。我使用Cassandra存储消息对象,使用芹菜异步拉入和推入数据库。除了一个芹菜任务外,一切都很好;使用相同代码/类的其他任务也可以工作。下面是代码逻辑的粗略分解:

db_manager = DBManager()

class User(object):
    def __init__(self, user_id):
        ... normal init stuff ...
        self.loader()

    @run_async
    def loader(self):
        ... loads from database if found, otherwise pulls from API ...

    # THIS WORKS
    @celery.task(name='user-to-db', filter=task_method)
    def to_db(self):
         # db_manager is a custom backend that handles relevant db reads, writes, etc.
         db_manager.add('users', self.user_payload)

     # THIS WORKS
     @celery.task(name='load-friends', filter=task_method)
     def load_friends(self):
          # Checks secondary redis index for friends of user
          friends = redis.srandmember('users:the-users-id:friends', self.id, 20)
          if not friends:
               profiles = load_friends_from_api(user_id=self.id)
          else:
               query = "SELECT * FROM keyspace.users WHERE id IN ({friends})".format(friends=friends)
          # Init a User object for every friend
          loaded_friends = [User(friend) for friend in profiles]
          # Returns a class container with all the instances of User(friend), accessible through a class property
          return FriendContainer(self.id, loaded_friends)

     # THIS DOES NOT WORK
     @celery.task(name='get-user-messages', filter=task_method)
     def get_user_messages(self):
          # THIS IS WHERE IT FAILS #
          messages = db_manager.get("SELECT message FROM keyspace.message_timelines WHERE user_id = {user_id}".format(user_id=self.id))
          # THAT LINE ABOVE #

          # Init a message class object for every message payload in database
          msgs = [Message(m, user=self) for m in messages]
          # Returns a message container class holding all the message objects, accessible through a class property
          return MessageContainer(msgs)
最后一个类方法引发错误:

File "/usr/local/lib/python2.7/dist-packages/kombu/serialization.py", line 356, in pickle_dumps

return dumper(obj, protocol=pickle_protocol)

EncodeError: Can't pickle <class 'cassandra.io.eventletreactor.message'>: attribute lookup cassandra.io.eventletreactor.message failed
这是来自
DBManager()
的方法:

我已经读到芹菜任务类外方法是一种实验性的方法,但我不明白为什么所有其他方法都是使用同一个实例
DBManager
的任务

问题似乎局限于用户定义的类型
message
在Cassandra驱动程序中不太好;但是,如果我在芹菜任务本身中运行
DBManager
中的
get
方法,它会工作。
也就是说,如果我复制/粘贴将错误从
DBManager.get
抛出到
User.get\u User\u messages
中的代码,它工作正常。如果我试图从
User.get\u User\u messages
中调用
DBManager.get
,它会中断

我就是不知道问题出在哪里。我可以做以下所有的很好

  • 在不使用芹菜的情况下运行
    get\u user\u messages
    方法,它就可以工作了
  • 如果我在芹菜任务方法本身中正确运行
    get
    method代码,则使用芹菜运行
    get\u user\u messages
    方法
  • 我可以运行注册为芹菜任务的其他方法,这些方法指向
    DBManager
    中使用Cassandra驱动程序的其他方法,甚至是将相同的
    消息
    用户定义类型插入数据库的方法
  • 我自己也试过用不同的组合来酸洗所有的东西,但无法重现错误
  • 我没有尝试过的内容:

  • 将序列化程序更改为
    json
    yaml
    。db有效负载中有几个便利项不会使用这两个项中的任何一个进行序列化
  • 使用
    dill
    代替
    pickle
    。这似乎不需要切换序列化程序,因为我可以让各个部分单独工作
  • 我可以直接通过Cassandra驱动程序而不是我的
    DBManager
    类来运行查询,但我觉得这应该是可以解决的,我只是缺少了一些非常非常明显的东西,非常明显,以至于我看不到它。如有任何关于在何处查找的建议,将不胜感激


    就相关性而言:Cassandra 3.3、CQL 3.4、DataStax python驱动程序3.1

    Meh,我发现了问题所在,而且非常明显。我想我实际上并没有试着腌制所有的东西,只是大部分的东西,而且我在凌晨4点调试时也没有意识到这一点

    无论如何,
    cassandra.row_factory=dict_factory
    在用户定义的类型上调用时,实际上并不会以dict的形式返回所有内容。它给出了一个dict
    {'label':message(x='this',y='that')}
    ,其中
    message
    是一个namedtuple。Cassandra驱动程序在类实例中动态创建namedtuple,因此pickle无法找到它

    messages = db_manager.get("SELECT message FROM keyspace.message_timelines WHERE user_id = {user_id}".format(user_id=self.id))
    
    class DBManager(object):
        ... stuff ...
    
        def get(self, query):
            # I do some stuff to prepare the query, namely substituting `WHERE this = that` for `WHERE this = ?` to create a Cassandra prepared statement.
            statement = cassandra.prepare(query_prepared)
            # I want these messages as a dict, not the default namedtuple
            cassandra.row_factory = dict_factory
            # User id is parsed out of query
            results = cassandra.execute(statement, (user_id,))
            rows = results.current_rows
            # rows is a list of dicts, no weird class references or anything in there
            return rows