frictionlessdata / tabulator-py

Python library for reading and writing tabular data via streams.
https://frictionlessdata.io
MIT License
235 stars 42 forks source link

Non-serializable types passed to JSON writer causes failure to save table. #339

Closed mhangaard closed 3 years ago

mhangaard commented 3 years ago

Overview

Table.save fails to export as JSON format if there are number types in the Table.schema.

To reproduce:

  1. Use the CSV from this example and save as 'people.csv'
  2. Add a .0 to make the "Age" type read as a float.
  3. Then
    table = Table('people.csv')
    table.infer()
    print(table.read(keyed=True))
    table.save('people.json', format='json', keyed=True)

    Output:

    
    [{'Name': 'Jill', 'Email': 'jill@foo.com', 'Age': Decimal('25.0')}, {'Name': 'Jack', 'Email': 'jackbar.com', 'Age': Decimal('33.0')}]
    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-242-01a5e53b8e4f> in <module>
      2 table.infer()
      3 print(table.read(keyed=True))
    ----> 4 table.save('people.json', format='json', keyed=True)

~/anaconda3/envs/qprops/lib/python3.7/site-packages/tableschema/table.py in save(self, target, storage, options) 423 if storage is None: 424 with Stream(self.iter, headers=self.__schema.headers) as stream: --> 425 stream.save(target, options) 426 return True 427

~/anaconda3/envs/qprops/lib/python3.7/site-packages/tabulator/stream.py in save(self, target, format, encoding, options) 728 # Write data to target 729 writer = writer_class(writer_options) --> 730 return writer.write(self.iter(), target, headers=self.headers, encoding=encoding) 731 732 # Private

~/anaconda3/envs/qprops/lib/python3.7/site-packages/tabulator/writers/json.py in write(self, source, target, headers, encoding) 37 count += 1 38 with open(target, 'w') as file: ---> 39 json.dump(data, file, indent=2) 40 return count

~/anaconda3/envs/qprops/lib/python3.7/json/init.py in dump(obj, fp, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw) 177 # could accelerate with writelines in some versions of Python, at 178 # a debuggability cost --> 179 for chunk in iterable: 180 fp.write(chunk) 181

~/anaconda3/envs/qprops/lib/python3.7/json/encoder.py in _iterencode(o, _current_indent_level) 427 yield _floatstr(o) 428 elif isinstance(o, (list, tuple)): --> 429 yield from _iterencode_list(o, _current_indent_level) 430 elif isinstance(o, dict): 431 yield from _iterencode_dict(o, _current_indent_level)

~/anaconda3/envs/qprops/lib/python3.7/json/encoder.py in _iterencode_list(lst, _current_indent_level) 323 else: 324 chunks = _iterencode(value, _current_indent_level) --> 325 yield from chunks 326 if newline_indent is not None: 327 _current_indent_level -= 1

~/anaconda3/envs/qprops/lib/python3.7/json/encoder.py in _iterencode_dict(dct, _current_indent_level) 403 else: 404 chunks = _iterencode(value, _current_indent_level) --> 405 yield from chunks 406 if newline_indent is not None: 407 _current_indent_level -= 1

~/anaconda3/envs/qprops/lib/python3.7/json/encoder.py in _iterencode(o, _current_indent_level) 436 raise ValueError("Circular reference detected") 437 markers[markerid] = o --> 438 o = _default(o) 439 yield from _iterencode(o, _current_indent_level) 440 if markers is not None:

~/anaconda3/envs/qprops/lib/python3.7/json/encoder.py in default(self, o) 177 178 """ --> 179 raise TypeError(f'Object of type {o.class.name} ' 180 f'is not JSON serializable') 181

TypeError: Object of type Decimal is not JSON serializable


---
Please preserve this line to notify @roll (lead of this repository)
mhangaard commented 3 years ago

Sorry this was the wrong repo. I opened the correct issue here: https://github.com/frictionlessdata/tableschema-py/issues/288