【问题标题】:Code fails to run when there is no data没有数据时代码无法运行
【发布时间】:2018-03-30 08:17:31
【问题描述】:

当我运行下面的查询并且["VT","NCR","N","DT","RD"], 等值中没有数据时,查询失败。

带有

的错误信息
ValueError: dict contains fields not in fieldnames: ‘VT’

有没有办法说如果任何值中没有数据仍然继续运行查询以获取python中具有数据的值的数据?
例如:“TRY”、“CATCH”或“PASS”方法?

我已经为此苦苦挣扎了好几天,有人可以告诉我如何做到这一点吗?

我的代码:

from datetime import datetime
from elasticsearch import Elasticsearch
import csv

es = Elasticsearch(["9200"])


res = es.search(index="search", body=
                {
                    "_source": ["VT","NCR","N","DT","RD"],
                    "query": {

                        "bool": {
                            "must": [{"range": {"VT": {
                                            "gte": "now/d",
                                            "lte": "now+1d/d"}}},

                                {"wildcard": {"user": "mike*"}}]}}},size=10)


csv_file = 'File_' + str(datetime.now().strftime('%Y_%m_%d - %H.%M.%S')) + '.csv'


header_names = { 'VT': 'Date', 'NCR': 'ExTime', 'N': 'Name', 'DT': 'Party', ' RD ': 'Period'}



with open(csv_file, 'w', newline='') as f:
    header_present  = False
    for doc in res['hits']['hits']:
        my_dict = doc['_source']
        if not header_present:
            w = csv.DictWriter(f, my_dict.keys())
            w.writerow(header_names,) 
            header_present = True
             w.writerow(my_dict)

【问题讨论】:

  • 查找dict.get()
  • 你能告诉我如何在我的代码中使用它吗?
  • 错误在哪里?请显示完整的回溯
  • 您从未在此处分配名为 VTDT 的变量。或者你缺少一些代码
  • @ cricket - Traceback(最近一次通话最后一次):文件“C:/Users/Rich/.PyCharmCE2017.2/config/scratches/TRY.py”,第 57 行,在 w .writerow(header_names,) # 将在正确的位置写入 DATE、TIME、... 文件“C:\Users\Rich\AppData\Local\Programs\Python\Python36-32\lib\csv.py”,第 155 行,在 writerow 返回 self.writer.writerow(self._dict_to_list(rowdict)) 文件“C:\Users\Rich\AppData\Local\Programs\Python\Python36-32\lib\csv.py”,第 151 行,在 _dict_to_list + ", ".join([repr(x) for x in wrong_fields])) ValueError: dict contains fields not in fieldnames: 'VT'

标签: python python-3.x csv dictionary elasticsearch


【解决方案1】:

我想指出你评论中的一个缺陷

 # will write DATE, TIME, ... in correct place
 w.writerow(header_names,)

实际上,它会在键的标题下写出字典的值...因此,您基本上是在编写两个标题。

关于错误according to the documentation,您可以忽略缺少的字段并在它们不存在时设置默认值

可选的restval 参数指定在字典缺少fieldnames 中的键时要写入的值。如果传递给 writerow() 方法的字典包含字段名中未找到的键,则可选的 extrasaction 参数指示要采取的操作。如果设置为“raise”,默认值,则会引发 ValueError。如果设置为 'ignore',则字典中的额外值将被忽略。

例如

with open(csv_file, 'w', newline='') as f:
    # Open one csv for all the results 
    w = csv.DictWriter(f, fieldnames=header_names.keys(), restval='', extrasaction='ignore') 
    # There's only one header, don't need a boolean flag 
    w.writeheader()  
    # proceed to write results 
    for doc in res['hits']['hits']:
        my_dict = doc['_source']
        # Parse this dictionary however you need to write a valid CSV row 
        w.writerow(my_dict)

否则,不要使用 DictWriter 并自己形成 CSV 行。您可以使用dict.get() 提取值,但设置数据中不存在的默认值

【讨论】:

  • 你能告诉我怎么做吗?老实说,我正在为此苦苦挣扎
  • 究竟该怎么做?我在这里给出了两个选择......我可能会建议退后一步,生成假数据,并了解 DictWriter 的来龙去脉,并确定你是否真的需要它。我会指出 w.writerow(header_names,) 看起来没有必要,除非您确实想要“双”标题
  • 从您的建议听起来 dict.get() 会很好用,因为您说“您可以使用 dict.get() 来提取值,但设置不存在于数据”,但我不确定如何使用 dict.get()。除非你愿意告诉我如何使用我上面的代码
  • 我刚刚尝试了上面的代码,但在 fieldnames=my_dict.keys 上出现错误
  • 我相信你可以在其他地方找到很多例子,例如vt = my_dict.get('VT', 'default VT')
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多