3

I'm currently using RethinkDB, which has a nice web UI with a Data Explorer which allows the user to print out the contents of the database like this:

enter image description here

Note that each key-value pair starts on a new line, and the keys and values (mostly) have different colors. By contrast, if I print out the same using iPython, I get an almost illegible result:

enter image description here

This is slightly ameliorated if I iterate over the cursor and print each item, like so:

enter image description here

However, this requires more typing and still doesn't look as good as the RethinkDB web UI. Is there perhaps an iPython plugin that I can install to improve the appearance of the printed output?

(I had a look at pprint, but this seems to control only the positioning of the text and not its color).

Kurt Peek
  • 52,165
  • 91
  • 301
  • 526
  • At your comment regarding PPrint: is indentation of pprint not sufficient? Removing the unicode of a string is also hard: http://stackoverflow.com/questions/761361/suppress-the-uprefix-indicating-unicode-in-python-strings – RvdK Oct 13 '16 at 10:39

2 Answers2

3

You could use json.dumps():

import json 

for row in r.db(....).run(conn):
    print(json.dumps(row, indent=4))

Although this does not display the keys in sorted order, as appears to be the case in the example, it might be sufficient for your needs. As pointed out by @coder, you json.dumps() can sort the keys by specifying the sort_keys=True parameter.

for row in r.db(....).run(conn):
    print(json.dumps(row, indent=4, sort_keys=True))

It might also be possible to print the object directly (haven't tested this):

print(json.dumps(r.db(....).run(conn), indent=4, sort_keys=True)

which might also print out the surrounding "list" object.


To handle objects that do not support serialisation to JSON you can use a custom JSONEncoder. Here is an example which handles datetime.datetime objects:

from datetime import datetime

class DateTimeAwareJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            tz = obj.tzname()
            return obj.ctime() + (' {}'.format(tz) if tz else '')
        return super(DateTimeAwareJSONEncoder, self).default(obj)

for row in r.db(....).run(conn):
    print(json.dumps(row, indent=4, sort_keys=True, cls=DateTimeAwareJSONEncoder))

You can use datetime.strftime() to format the date time string as required.

mhawke
  • 84,695
  • 9
  • 117
  • 138
  • 3
    if needed you can sort the keys using `json.dumps` with the parameter `sort_keys=True` ... – coder Oct 13 '16 at 11:00
  • This does not work for dicts with non-JSON-serializable objects, e.g. `Decimal`. – chris Apr 02 '18 at 21:10
  • @ChrisAnderson: so write a custom JSON encoder for `Decimal` as I've shown for `datetime` objects. – mhawke Apr 02 '18 at 21:53
0

mhawke's answer works if one adds the keyword argument time_format="raw" to RethinkDB's run() command. (Otherwise, you get a TypeError because RethinkDB's object containing the time zone is not JSON serializable). The result looks like this:

enter image description here

which is much more legible. A slight drawback is that the epoch_time is more difficult to interpret than the original time format.

Community
  • 1
  • 1
Kurt Peek
  • 52,165
  • 91
  • 301
  • 526
  • You can use a custom `JSONEncoder` to handle the `datetime` objects. See my updated answer. – mhawke Oct 14 '16 at 03:29