Exemplo n.º 1
0
    def from_object(cls, obj, row_names=None, column_types=None):
        """
        Create a new table from a Python object with a structure that mirrors
        a deserialized JSON object. Its contents should be an array
        containing a dictionary for each "row". Nested objects or lists will
        also be parsed. For example, this object:

        .. code-block:: python

            {
                'one': {
                    'a': 1,
                    'b': 2,
                    'c': 3
                },
                'two': [4, 5, 6],
                'three': 'd'
            }

        Would generate these columns and values:

        .. code-block:: python

            {
                'one/a': 1,
                'one/b': 2,
                'one/c': 3,
                'two.0': 4,
                'two.1': 5,
                'two.2': 6,
                'three': 'd'
            }

        Column names and types will be inferred from the data. Not all rows are
        required to have the same keys. Missing elements will be filled in with
        null.

        :param obj:
            Filepath or file-like object from which to read JSON data.
        :param row_names:
            See :meth:`Table.__init__`.
        :param column_types:
            See :meth:`Table.__init__`.
        """
        column_names = []
        row_objects = []

        for sub in obj:
            parsed = utils.parse_object(sub)

            for key in parsed.keys():
                if key not in column_names:
                    column_names.append(key)

            row_objects.append(parsed)

        rows = []

        for sub in row_objects:
            r = []

            for name in column_names:
                r.append(sub.get(name, None))

            rows.append(r)

        return Table(rows, column_names, row_names=row_names, column_types=column_types)
Exemplo n.º 2
0
    def from_object(cls, obj, row_names=None, column_types=None):
        """
        Create a new table from a Python object.

        The object should be a list containing a dictionary for each "row".
        Nested objects or lists will also be parsed. For example, this object:

        .. code-block:: python

            {
                'one': {
                    'a': 1,
                    'b': 2,
                    'c': 3
                },
                'two': [4, 5, 6],
                'three': 'd'
            }

        Would generate these columns and values:

        .. code-block:: python

            {
                'one/a': 1,
                'one/b': 2,
                'one/c': 3,
                'two.0': 4,
                'two.1': 5,
                'two.2': 6,
                'three': 'd'
            }

        Column names and types will be inferred from the data.

        Not all rows are required to have the same keys. Missing elements will
        be filled in with null values.

        :param obj:
            Filepath or file-like object from which to read JSON data.
        :param row_names:
            See :meth:`.Table.__init__`.
        :param column_types:
            See :meth:`.Table.__init__`.
        """
        column_names = []
        row_objects = []

        for sub in obj:
            parsed = utils.parse_object(sub)

            for key in parsed.keys():
                if key not in column_names:
                    column_names.append(key)

            row_objects.append(parsed)

        rows = []

        for sub in row_objects:
            r = []

            for name in column_names:
                r.append(sub.get(name, None))

            rows.append(r)

        return Table(rows,
                     column_names,
                     row_names=row_names,
                     column_types=column_types)
Exemplo n.º 3
0
    def from_json(cls,
                  path,
                  row_names=None,
                  key=None,
                  newline=False,
                  **kwargs):
        """
        Create a new table from a JSON file. Contents should be an array
        containing a dictionary for each "row". Nested objects or lists will
        also be parsed. For example, this object:

        .. code-block:: javascript

            {
                'one': {
                    'a': 1,
                    'b': 2,
                    'c': 3
                },
                'two': [4, 5, 6],
                'three': 'd'
            }

        Would generate these columns and values:

        .. code-block:: python

            {
                'one/a': 1,
                'one/b': 2,
                'one/c': 3,
                'two.0': 4,
                'two.1': 5,
                'two.2': 6,
                'three': 'd'
            }

        Column names and types will be inferred from the data. Not all rows are
        required to have the same keys. Missing elements will be filled in with
        null.

        If the file contains a top-level dictionary you may specify what
        property contains the row list using the `key` parameter.

        `kwargs` will be passed through to :meth:`json.load`.

        :param path:
            Filepath or file-like object from which to read JSON data.
        :param row_names:
            See :meth:`Table.__init__`.
        :param key:
            The key of the top-level dictionary that contains a list of row
            arrays.
        :param newline:
            If `True` then the file will be parsed as "newline-delimited JSON".
        """
        if newline:
            js = []

            if hasattr(path, 'read'):
                for line in path:
                    js.append(
                        json.loads(line,
                                   object_pairs_hook=OrderedDict,
                                   parse_float=Decimal,
                                   **kwargs))
            else:
                with open(path, 'r') as f:
                    for line in f:
                        js.append(
                            json.loads(line,
                                       object_pairs_hook=OrderedDict,
                                       parse_float=Decimal,
                                       **kwargs))
        else:
            if hasattr(path, 'read'):
                js = json.load(path,
                               object_pairs_hook=OrderedDict,
                               parse_float=Decimal,
                               **kwargs)
            else:
                with open(path, 'r') as f:
                    js = json.load(f,
                                   object_pairs_hook=OrderedDict,
                                   parse_float=Decimal,
                                   **kwargs)

        if isinstance(js, dict):
            if not key:
                raise TypeError(
                    'When converting a JSON document with a top-level dictionary element, a key must be specified.'
                )

            js = js[key]

        column_names = []
        row_objects = []

        for obj in js:
            parsed = utils.parse_object(obj)

            for key in parsed.keys():
                if key not in column_names:
                    column_names.append(key)

            row_objects.append(parsed)

        rows = []

        for obj in row_objects:
            r = []

            for name in column_names:
                r.append(obj.get(name, None))

            rows.append(r)

        return Table(rows, column_names, row_names=row_names)
Exemplo n.º 4
0
    def from_json(cls, path, row_names=None, key=None, newline=False, **kwargs):
        """
        Create a new table from a JSON file. Contents should be an array
        containing a dictionary for each "row". Nested objects or lists will
        also be parsed. For example, this object:

        .. code-block:: javascript

            {
                'one': {
                    'a': 1,
                    'b': 2,
                    'c': 3
                },
                'two': [4, 5, 6],
                'three': 'd'
            }

        Would generate these columns and values:

        .. code-block:: python

            {
                'one/a': 1,
                'one/b': 2,
                'one/c': 3,
                'two.0': 4,
                'two.1': 5,
                'two.2': 6,
                'three': 'd'
            }

        Column names and types will be inferred from the data. Not all rows are
        required to have the same keys. Missing elements will be filled in with
        null.

        If the file contains a top-level dictionary you may specify what
        property contains the row list using the `key` parameter.

        `kwargs` will be passed through to :meth:`json.load`.

        :param path:
            Filepath or file-like object from which to read CSV data.
        :param row_names:
            See :meth:`Table.__init__`.
        :param key:
            The key of the top-level dictionary that contains a list of row
            arrays.
        :param newline:
            If `True` then the file will be parsed as "newline-delimited JSON".
        """
        if newline:
            js = []

            if hasattr(path, 'read'):
                for line in path:
                    js.append(json.loads(line, object_pairs_hook=OrderedDict, parse_float=Decimal, **kwargs))
            else:
                with open(path, 'r') as f:
                    for line in f:
                        js.append(json.loads(line, object_pairs_hook=OrderedDict, parse_float=Decimal, **kwargs))
        else:
            if hasattr(path, 'read'):
                js = json.load(path, object_pairs_hook=OrderedDict, parse_float=Decimal, **kwargs)
            else:
                with open(path, 'r') as f:
                    js = json.load(f, object_pairs_hook=OrderedDict, parse_float=Decimal, **kwargs)

        if isinstance(js, dict):
            if not key:
                raise TypeError('When converting a JSON document with a top-level dictionary element, a key must be specified.')

            js = js[key]

        column_names = []
        row_objects = []

        for obj in js:
            parsed = utils.parse_object(obj)

            for key in parsed.keys():
                if key not in column_names:
                    column_names.append(key)

            row_objects.append(parsed)

        rows = []

        for obj in row_objects:
            r = []

            for name in column_names:
                r.append(obj.get(name, None))

            rows.append(r)

        return Table(rows, column_names, row_names=row_names)