ValueError: String does not contain a date. Issues with Delorean, Dateutil and functions working in some places, but not others

ValueError: String does not contain a date. Issues with Delorean, Dateutil and functions working in some places, but not others

所以,我想我快疯了。我正在使用 Delorean 将 CSV 字段 row[15] 中的字符串转换为日期,然后将其传递给 parse().epoch。这是我的进口商品:

import sys
import os.path
import requests
import json
import csv
import glob2
import shutil
from time import sleep
from time import gmtime, strftime
from delorean import Delorean
from delorean import parse
from delorean import epoch

我现在有这个功能:

def ref_date_epoch():
    ref_date_epoch_result = "{ref_date}000".format(ref_date=int(parse(row[15]).epoch))
    return ref_date_epoch_result

这成功地 returns 一个 Unix 时间对象(至少是我可以使用的格式)。但是,当我稍后在我的代码中引用此函数时,就像这样(它作为 referral_date 键的值朝向底部):

        update_company_payload = {
                    "properties": [
                        {"name":"name", "value": row[0] },
                        {"name":"hubspot_owner_id", "value": hubspot_owner_id },
                        {"name":"account_type", "value": row[2] },
                        {"name":"industry", "value": row[3] },
                        {"name":"product", "value": row[4] },
                        {"name":"address", "value": row[5] },
                        {"name":"address2", "value": row[6] },
                        {"name":"city", "value": row[7] },
                        {"name":"state", "value": row[8] },
                        {"name":"zip", "value": row[9] },
                        {"name":"country", "value": row[10] },
                        {"name":"phone", "value": row[11] },
                        {"name":"website", "value": row[12] },
                        {"name":"credit_safe_limit", "value": row[13] },
                        {"name":"credit_safe_rating", "value": row[14] },
                        {"name":"referral_date", "value": ref_date_epoch() },
                        {"name":"referred_from", "value": row[16] },
                        {"name":"referred_to", "value": row[17] },
                        {"name":"source", "value": row[18] }
                      ]
                }

我明白了:

Traceback (most recent call last):
  File "wta_goldvision_company_import.py", line 187, in <module>
    run()
  File "wta_goldvision_company_import.py", line 183, in run
    update_company(create_company(), get_owner_id())
  File "wta_goldvision_company_import.py", line 162, in update_company
    {"name":"referral_date", "value": ref_date_epoch() },
  File "wta_goldvision_company_import.py", line 141, in ref_date_epoch
    ref_date_epoch_result = "{ref_date}000".format(ref_date=int(parse(row[15]).epoch))
  File "build/bdist.macosx-10.11-intel/egg/delorean/interface.py", line 68, in parse
  File "build/bdist.macosx-10.11-intel/egg/dateutil/parser.py", line 1161, in parse
  File "build/bdist.macosx-10.11-intel/egg/dateutil/parser.py", line 555, in parse
ValueError: String does not contain a date.

为什么这个函数单独运行,但在别处使用时却不行?我试过像这样手动输入日期:

ref_date_epoch_result = "{ref_date}000".format(ref_date=int(parse("23/12/2015").epoch))

而且效果很好。为什么 dateutil 解析函数在 JSON 有效载荷之外做它的事情没有问题,但一旦它在那个东西内部被引用,它似乎无法解释 [=17 的值=] 作为一个字符串 - 我错过了什么?

最新回溯:

23/03/2015
Hermes Transport Logistics GMBH updated successfully.

Traceback (most recent call last):
  File "wta_goldvision_company_import.py", line 187, in <module>
    run()
  File "wta_goldvision_company_import.py", line 183, in run
    update_company(create_company(), get_owner_id())
  File "wta_goldvision_company_import.py", line 162, in update_company
    {"name":"referral_date", "value": ref_date_epoch(row[15]) },
  File "wta_goldvision_company_import.py", line 142, in ref_date_epoch
    return "{ref_date}000".format(ref_date=int(parse(datestr).epoch))
  File "build/bdist.macosx-10.11-intel/egg/delorean/interface.py", line 68, in parse
  File "build/bdist.macosx-10.11-intel/egg/dateutil/parser.py", line 1161, in parse
  File "build/bdist.macosx-10.11-intel/egg/dateutil/parser.py", line 555, in parse
ValueError: String does not contain a date.

这是上面驻留的整个函数(它又是一个更大整体的一部分):

def update_company( company_id, hubspot_owner_id ):

    # Allows HubSpot 15 seconds to reflect the changes made by the create_company() and get_owner_id() functions.
    sleep(15.0)

    # Open the CSV, use commas as delimiters, store it in a list called "data", then find the length of that list.
    with open(os.path.basename(theCSV),"r") as f:
        reader = csv.reader(f, delimiter = ",", quotechar="\"")
        next(reader)
        for row in reader:

            def ref_date_epoch(datestr):
                print(datestr)
                return "{ref_date}000".format(ref_date=int(parse(datestr).epoch))

            # Set up the JSON payload ...
            update_company_payload = {
                        "properties": [
                            {"name":"name", "value": row[0] },
                            {"name":"hubspot_owner_id", "value": hubspot_owner_id },
                            {"name":"account_type", "value": row[2] },
                            {"name":"industry", "value": row[3] },
                            {"name":"product", "value": row[4] },
                            {"name":"address", "value": row[5] },
                            {"name":"address2", "value": row[6] },
                            {"name":"city", "value": row[7] },
                            {"name":"state", "value": row[8] },
                            {"name":"zip", "value": row[9] },
                            {"name":"country", "value": row[10] },
                            {"name":"phone", "value": row[11] },
                            {"name":"website", "value": row[12] },
                            {"name":"credit_safe_limit", "value": row[13] },
                            {"name":"credit_safe_rating", "value": row[14] },
                            {"name":"referral_date", "value": ref_date_epoch(row[15]) },
                            {"name":"referred_from", "value": row[16] },
                            {"name":"referred_to", "value": row[17] },
                            {"name":"source", "value": row[18] }
                          ]
                    }
            #'https://api.hubapi.com/companies/v2/companies/10444744?hapikey=demo'
            update_company_call = "https://api.hubapi.com/companies/v2/companies/{created_company_id}?hapikey={hapikey}".format(hapikey=wta_hubspot_api_key, created_company_id=company_id)
            headers = {'content-type': 'application/json'}
            data = json.dumps(update_company_payload)
            update_company_response = requests.put(update_company_call, data=data, headers=headers)
            #print(json.dumps(update_company_response.json(), sort_keys=True, indent=4))
            #print (update_company_response.status_code)
            if update_company_response.status_code == 200:
                print("{companyName} updated successfully.".format(companyName=row[0]))
            else:
                print("Something went wrong with the {companyName} update.".format(companyName=row[0]))
                print(json.dumps(update_company_response.json(), sort_keys=True, indent=4))

似乎 row[15] 在某行上是 None。 CSV 文件中可能是空值?

此外,您可以在循环外定义 ref_date_epoch 函数。


旧答案:

不要将 row[15] 放入 ref_date_epoch 函数中,而是将其作为参数提供。

def ref_date_epoch(datestr):
    return "{ref_date}000".format(ref_date=int(parse(datestr).epoch))

然后

...
{"name":"referral_date", "value": ref_date_epoch(row[15])},
...

解决方案:

事实证明,精神疲劳使我们所有人都变得愚蠢 - 我正在循环浏览 CSV,显然第一行,结果证明是我的测试行,是一段时间内唯一实际包含日期的行,因此为什么它到达第二行时崩溃了。所以我将 ref_date_epoch 函数修改为:

        def ref_date_epoch(datestr):
            if len(datestr) > 0:
                return "{ref_date}000".format(ref_date=int(parse(datestr).epoch))
            else:
                None