【问题标题】:Pymongo - ValueError: NaTType does not support utcoffset when using insert_manyPymongo - ValueError: NaTType 在使用 insert_many 时不支持 utcoffset
【发布时间】:2017-02-14 14:07:45
【问题描述】:

我正在尝试将文档从一个数据库增量复制到另一个数据库。

某些字段包含以下格式的日期时间值:

2016-09-22 00:00:00

而其他人是这种格式:

2016-09-27 09:03:08.988

我像这样提取和插入文档:

pd.DataFrame(list(db_prod.db_name.collction_name.find({'_updated_at': {'$gt': last_added_timestamp}}).sort('_updated_at', 1)))
add = (df.to_dict('records'))

try:
    db_incremental.other_db.collection_name.insert_many(add)
except BulkWriteError as bwe:
    print(bwe.details)

这是错误:

  File "/usr/local/lib/python2.7/dist-packages/pymongo/collection.py", line 684, in insert_many
    blk.execute(self.write_concern.document)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/bulk.py", line 470, in execute
    return self.execute_command(sock_info, generator, write_concern)
  File "/usr/local/lib/python2.7/dist-packages/pymongo/bulk.py", line 302, in execute_command
    run.ops, True, self.collection.codec_options, bwc)
  File "pandas/tslib.pyx", line 663, in pandas.tslib._make_error_func.f (pandas/tslib.c:14736)
ValueError: NaTType does not support utcoffset

我实际上不需要修改时间戳,只需按原样插入即可。

任何帮助表示赞赏。

【问题讨论】:

  • 每次都需要手动查找by key and value。哪个更好?
  • 我想在文档中插入所有字段和值
  • 替换键是不同的条目,所以写一个尝试,除了引发错误,插入新的键和值,删除旧的。
  • 恐怕我不太关注。我已经在我的 insert_many 中使用了 try/except。我没有使用替换。
  • Mongo 程序:替换/更改密钥等于插入新

标签: python mongodb pymongo


【解决方案1】:

显然它对我有用

df.fillna("-",inplace=True)

【讨论】:

  • 不是一个好的解决方案,因为您将无法再在 mongo 的字段上进行日期时间操作
【解决方案2】:

用 Pandas 可以解释的 None 值替换它

df[['_updated_at']] = df[['_updated_at']].astype(object).where(df[['_updated_at']].notnull(), None)

【讨论】:

    【解决方案3】:

    单元格可能没有相同的日期时间格式,您应该先使用 pandas.DataFrame.apply 对其进行标准化,这里是如何做到这一点的示例。

    import datetime as dt
    
    def handleString(probably_string):
        # string pattern: 2016-09-27 09:03:08.988
        try:
            _date, _time = probably_string.split(' ')
            _year, _month, _day = (int(x) for x in _date.plit('-'))
            _hour, _minute, _second = (int(x) for x in _time.split(':'))
            return dt.datetime(_year, _month, _day, _hour, _minute, _second)
        except AttributeError:
            # it's NoneType oject
            # but you should return datetime object for mongodb datetime field
            return dt.datetime(1970,1,1)
        except ValueError:
            # not enough values to unpack
            # but you should return datetime object for mongodb datetime field
            return dt.datetime(1970,1,1)
    
    def formatTime(row, column_name):
        datetime_cell = row[column_name]
        try:
            _second = datetime_cell.second
            return datetime_cell.replace(second=_second, microsecond=0)
        catch AttributeError:
            return handleString(datetime_cell)
    
    time_column = 'time_field'
    df[time_column] = df.apply(lambda row: formatTime(row, time_column), axis='columns')
    

    【讨论】:

      【解决方案4】:
      def new_replace(k):
          return k.replace(tzinfo=None)
          
      
      df[time_column]= df.apply(lambda row: new_replace(row[time_column]),axis = 1)
      

      这在我的情况下有效。您也可以根据您的情况在 new_replace 函数中添加 try except。

      【讨论】:

        猜你喜欢
        • 2019-02-25
        • 2016-11-16
        • 1970-01-01
        • 2016-09-22
        • 1970-01-01
        • 1970-01-01
        • 2021-05-30
        • 1970-01-01
        • 2021-03-05
        相关资源
        最近更新 更多