Python Google cloud firestore错误504已超过截止日期

Python Google cloud firestore错误504已超过截止日期,python,firebase,google-cloud-firestore,Python,Firebase,Google Cloud Firestore,我在python中有一个函数fore firestore,其中我为一个集合的所有用户执行for循环,然后我进入另一个集合获取一些度量,并在第一个集合中更新这些度量 我运行了函数,但在执行过程中的某个点,函数中断,导致以下错误: _Rendezvous Traceback (most recent call last) ~\Anaconda3\envs\work\lib\site-packages\google\api_core\grpc

我在python中有一个函数fore firestore,其中我为一个集合的所有用户执行for循环,然后我进入另一个集合获取一些度量,并在第一个集合中更新这些度量

我运行了函数,但在执行过程中的某个点,函数中断,导致以下错误:

_Rendezvous                               Traceback (most recent call last)
~\Anaconda3\envs\work\lib\site-packages\google\api_core\grpc_helpers.py in next(self)
     78         try:
---> 79             return six.next(self._wrapped)
     80         except grpc.RpcError as exc:

~\Anaconda3\envs\work\lib\site-packages\grpc\_channel.py in __next__(self)
    363     def __next__(self):
--> 364         return self._next()
    365 

~\Anaconda3\envs\work\lib\site-packages\grpc\_channel.py in _next(self)
    346             else:
--> 347                 raise self
    348             while True:

_Rendezvous: <_Rendezvous of RPC that terminated with:
    status = StatusCode.DEADLINE_EXCEEDED
    details = "Deadline Exceeded"
    debug_error_string = "{"created":"@1570660422.708000000","description":"Error received from peer ipv4:216.58.202.234:443","file":"src/core/lib/surface/call.cc","file_line":1052,"grpc_message":"Deadline Exceeded","grpc_status":4}"
>

The above exception was the direct cause of the following exception:

DeadlineExceeded                          Traceback (most recent call last)
<ipython-input-20-05c9cefdafb4> in <module>
----> 1 update_collection__persons()

<ipython-input-19-6e2bdd597a6e> in update_collection__persons()
     10     counter_secs = 0
     11 
---> 12     for person_doc in person_docs:
     13         person_dict = person_doc.to_dict()
     14         last_updated = person_dict['last_updated']

~\Anaconda3\envs\work\lib\site-packages\google\cloud\firestore_v1\query.py in stream(self, transaction)
    766         )
    767 
--> 768         for response in response_iterator:
    769             if self._all_descendants:
    770                 snapshot = _collection_group_query_response_to_snapshot(

~\Anaconda3\envs\work\lib\site-packages\google\api_core\grpc_helpers.py in next(self)
     79             return six.next(self._wrapped)
     80         except grpc.RpcError as exc:
---> 81             six.raise_from(exceptions.from_grpc_error(exc), exc)
     82 
     83     # Alias needed for Python 2/3 support.

~\Anaconda3\envs\work\lib\site-packages\six.py in raise_from(value, from_value)

DeadlineExceeded: 504 Deadline Exceeded
\u会合追踪(最近一次呼叫最后一次)
~\Anaconda3\envs\work\lib\site packages\google\api\u core\grpc\u helpers.py下一步(self)
78尝试:
--->79返回六。下一个(自我包装)
80除grpc.RpcError作为exc外:
~\Anaconda3\envs\work\lib\site packages\grpc\\u channel.py in\uuuuuuuuu next\uuuuuu(self)
363定义下一个定义(自身):
-->364返回自我。_next()
365
~\Anaconda3\envs\work\lib\site packages\grpc\\u channel.py in\u next(self)
346其他:
-->347提高自我
348虽然正确:
_会合地点:
上述异常是以下异常的直接原因:
死线超出回溯(最近一次呼叫上次)
在里面
---->1更新收集人员()
在update_collection__persons()中
10计数器秒=0
11
--->12对于个人文档中的个人文档:
13个人记录=个人记录到个人记录()
14 last_updated=个人记录['last_updated']
流中的~\Anaconda3\envs\work\lib\site packages\google\cloud\firestore\u v1\query.py(self,transaction)
766         )
767
-->768对于响应迭代器中的响应:
769如果自我所有后代:
770快照=\收集\组\查询\响应\快照(
~\Anaconda3\envs\work\lib\site packages\google\api\u core\grpc\u helpers.py下一步(self)
79返回六。下一个(自我包装)
80除grpc.RpcError作为exc外:
--->81六、从(例外情况。从grpc错误(exc),exc)
82
83#Python 2/3支持需要别名。
~\Anaconda3\envs\work\lib\site packages\six.py in raise\u from(value,from\u value)
超出死线:超过504个截止日期
我一直在寻找解决方案,信息不多,在这里我发现了一个类似的问题:

因此,我尝试使用此代码,但不起作用。这是我的功能:

def update_collection__persons():   
    persons = db.collection(u'collections__persons')
    person_docs = persons.stream()


    counter_secs = 0

    for person_doc in person_docs:
        person_dict = person_doc.to_dict()
        last_updated = person_dict['last_updated']
        last_processed = person_dict['last_processed']
        dt_last_updated = datetime(1, 1, 1) + timedelta(microseconds=last_updated/10)
        dt_last_processed = datetime(1, 1, 1) + timedelta(microseconds=last_processed/10)

        if dt_last_processed < dt_last_updated:
            orders = db.collection(u'collection__orders').where(u'email', u'==', person_dict['email'])
            orders_docs = orders.stream()

            sum_price = 0
            count = 0
            date_add_list = []

            for order_doc in orders_docs:
                order_dict = order_doc.to_dict() 
                sum_price += order_dict['total_price']
                count +=1
                date_add_list.append(order_dict['dateAdded'])
            if count > 0:
                data = {'metrics': {'LTV': sum_price,
                                    'AOV': sum_price/count,
                                    'Quantity_orders': count,
                                    'first_order_date': min(date_add_list),
                                    'last_order_date': max(date_add_list)},
                         'last_processed': int((datetime.utcnow() - datetime(1, 1, 1)).total_seconds() * 10000000)}

                 db.collection(u'collection__persons').document(person_dict['email']).set(data, merge = True)
def update_collection__persons():
persons=db.collection(u'collections\u__persons')
person\u docs=persons.stream()
计数器秒=0
对于个人文档中的个人文档:
person_dict=person_doc.to_dict()
last_updated=个人记录['last_updated']
last_processed=个人记录['last_processed']
dt_last_updated=日期时间(1,1,1)+时间增量(微秒=last_updated/10)
dt_last_processed=日期时间(1,1,1)+时间增量(微秒=last_processed/10)
如果dt_last_processed0:
数据={'metrics':{'LTV':总价,
“AOV”:总价/计数,
“数量订单”:计数,
“首次订单日期”:最小(日期添加列表),
“上次订单日期”:最大(日期添加列表)},
“上次处理”:int((datetime.utcnow()-datetime(1,1,1)).total_seconds()*10000000)}
db.collection(u'collection\u persons').document(person\u dict['email']).set(data,merge=True)
我创建了一个计数器,只是想看看函数是否总是在同一个查询中中断,但事实并非如此


此外,在运行该函数后,如果我看到一些随机用户,我会更新他们的数据,因此该函数正在工作,但在某个时间点中断,
persons.stream()
。与其在流式处理每个文档,不如尝试提前获取所有文档:

person_docs = [snapshot for snapshot in persons.stream()]
如果您有超过60秒的文档,请尝试使用递归函数

订单相同:

orders_docs = [snapshot for snapshot in orders.stream()]

我在获取所有文档以将其转换为JSON时遇到了这个问题

我是这样做的

def load_文档(自身,路径):
collection=self.db
节点=路径。拆分(“/”)
对于i,枚举中的节点(节点):
如果i%2==0:
集合=集合。集合(节点)
其他:
collection=collection.document(节点)
stream=collection.stream()
对于流中的文档:
打印(“*获取文档:{}”。格式(doc.get(“文件名”))
self.memes.append(self.\u fetch\u doc(doc))
def_fetch_doc(self,doc):
尝试:
返回{
“标题”:文件获取(“标题”),
“文件名”:doc.get(“文件名”),
“url”:文档获取(“url”)
}
除:
自取文件(文件)

如果出现异常,我会递归获取。

您能解释一下(游标)之后的开始是什么吗?他将光标初始化为none,因此当它的值与none不同时?start_after和no use this start_after之间有什么区别?当然,它是一个。该函数将一个大型查询一次拆分为1000个文档的批次。在获取1000个文档的批次后,该函数将第1000个文档作为que传递用鼠标移动光标以获取下一个1000个文档,
count\u集合(coll\u ref,count,docs[999].get())
。实际的异常是
死线超出了
,它发生在流中文档的
行而不是