【发布时间】:2019-01-25 17:20:45
【问题描述】:
所以我正在尝试通过云功能更新云 Firestore 中的日期时间字段,如下所示:
transaction.update(doc_ref, {'dateTimeField1': dateTimeValue})
Google 以%Y-%m-%dT%H:%M:%SZ 或%Y-%m-%dT%H:%M:%S.%fZ 格式在云函数的事件参数中将日期时间对象作为字符串发送。
例如:2019-01-25T15:25:03.881Z
我将它转换为日期时间对象如下:
try:
datetime_obj = datetime.datetime.strptime(datetime_obj, '%Y-%m-%dT%H:%M:%S.%fZ')
except:
datetime_obj = datetime.datetime.strptime(datetime_obj, '%Y-%m-%dT%H:%M:%SZ')
datetime_obj = datetime_obj.replace(tzinfo=timezone('UTC'))
但是当我尝试执行该操作时,我遇到了以下错误:
AttributeError: _nanosecond
回溯:File "/env/local/lib/python3.7/site-packages/google/cloud/firestore_v1beta1/batch.py", line 112, in update
reference._document_path, field_updates, option
File "/env/local/lib/python3.7/site-packages/google/cloud/firestore_v1beta1/_helpers.py", line 822, in pbs_for_update
update_pb = extractor.get_update_pb(document_path)
File "/env/local/lib/python3.7/site-packages/google/cloud/firestore_v1beta1/_helpers.py", line 459, in get_update_pb
name=document_path, fields=encode_dict(self.set_fields)
File "/env/local/lib/python3.7/site-packages/google/cloud/firestore_v1beta1/_helpers.py", line 215, in encode_dict
return {key: encode_value(value) for key, value in six.iteritems(values_dict)}
File "/env/local/lib/python3.7/site-packages/google/cloud/firestore_v1beta1/_helpers.py", line 215, in <dictcomp>
return {key: encode_value(value) for key, value in six.iteritems(values_dict)}
File "/env/local/lib/python3.7/site-packages/google/cloud/firestore_v1beta1/_helpers.py", line 169, in encode_value
return document_pb2.Value(timestamp_value=value.timestamp_pb())
File "/env/local/lib/python3.7/site-packages/google/api_core/datetime_helpers.py", line 278, in timestamp_pb
nanos = self._nanosecond or self.microsecond * 1000
AttributeError: _nanosecond
是否允许通过交易设置日期时间,或者我在这里遗漏了什么?
编辑:
代码sn-p:
@firestore.transactional
def update_datetime_field(transaction, doc_ref, datetime_value):
try:
datetime_obj = datetime.datetime.strptime(datetime_value, '%Y-%m-%dT%H:%M:%S.%fZ')
except:
datetime_obj = datetime.datetime.strptime(datetime_value, '%Y-%m-%dT%H:%M:%SZ')
datetime_obj = datetime_obj.replace(tzinfo=timezone('UTC'))
# Example of datetime_obj -> datetime.datetime(2019, 1, 25, 15, 25, 3, 881000, tzinfo=<UTC>)
transaction.update(doc_ref, {'datetimeField1': datetime_obj})
return True
更多信息:
- 当文档更新时触发上述代码
collection1/document1/collection2/document2 - datetime 对象是标准库中 python 的日期时间
- 我正在尝试通过使用 pytz 更改时区来将日期转换为 UTC
编辑 2:
更好的全图:
from firebase_admin import credentials, firestore
# initialize firebase admin sdk
creds = credentials.ApplicationDefault()
firebase_admin.initialize_app(creds,{'projectId': 'myProjectId'})
@firestore.transactional
def update_datetime_field(transaction, doc_ref, datetime_value):
try:
datetime_obj = datetime.datetime.strptime(datetime_value, '%Y-%m-%dT%H:%M:%S.%fZ')
except:
datetime_obj = datetime.datetime.strptime(datetime_value, '%Y-%m-%dT%H:%M:%SZ')
datetime_obj = datetime_obj.replace(tzinfo=timezone('UTC'))
# Example of datetime_obj -> datetime.datetime(2019, 1, 25, 15, 25, 3, 881000, tzinfo=<UTC>)
transaction.update(doc_ref, {'datetimeField1': datetime_obj})
return True
def update_datetime_in_transaction(event, context):
datetime_value = event['value']['fields']['datetimeField1']['timestampValue']
# this looks something like 2019-01-25T15:25:03.881Z
# prepare document reference to document
doc_ref = prepare_doc_ref(event, context)
# update_datetime_field
client = firestore.client()
transaction = client.transaction()
update_datetime_field(transaction, doc_ref, datetime_value)
return True
编辑 3:
【问题讨论】:
-
我不相信日期时间支持纳秒。
-
请编辑问题以显示重现问题的完整、最少的代码。或者,换句话说,显示您的整个 Cloud Function 代码,以及您正在做什么来触发它。
-
另外,请解释一下“日期时间”对象是什么意思。 Firestore 作为原生 Timestamp 类型字段,与许多系统所称的“日期时间”不同。
-
@DougStevenson 用简约代码 sn-p 更新了问题
-
如果我没记错的话,你的代码中就有错误。
strptime()的参数应该是datetime_value,而不是datetime_obj。
标签: python firebase transactions google-cloud-firestore firebase-admin