Search code examples
pythonpython-2.7mysql-pythonprettytable

Python PrettyTable printing table on same line


I'm using PrettyTable 'from_db_cursor' module to print nicely the responses I get from my sql requests. Everything works fine, my only problem is that for some of the queries i would like to print the table they are attached to one the same line like this:

countUnivers1:    countUnivers2:    countUnivers3:
+----------+      +----------+      +----------+
| COUNT(*) |      | COUNT(*) |      | COUNT(*) |
+----------+      +----------+      +----------+
| 1681943  |      |  51954   |      | 4140984  |
+----------+      +----------+      +----------+

but I can't manage to find out how to do this, here his the code I use for the moment:

i = 0
tables = []
with open(output, 'w+') as file:
    file.write(str(current_time) + '\n')
    for query in QUERIES.items():
        cur.execute(query[1])
        table = from_db_cursor(cur)
        if not re.search('countUnivers' ,query[0]):
            file.write('\n' + query[0] + ':\n')
            file.write(str(table) + '\n')
        else:
            if i < 6:
                file.write(query[0] + ':\t')
                tables.append(str(table))
                i += 1
            elif i == 6:
                file.write('\n')
                for t in tables:
                    file.write(str(table) + '\t')
                i = 0
                tables = []
    file.write('\nDatabase:\n' + json.dumps(dbParams, indent=4) + '\n')

This code outputs me:

countUnivers1:  countUnivers2:  countUnivers3:
+----------+
| COUNT(*) |
+----------+
| 1681943  |
+----------+    +----------+
| COUNT(*) |
+----------+
|  51954   |
+----------+    +----------+
| COUNT(*) |
+----------+
| 4140984  |
+----------+

QUERIES here is a OrderedDict filled with SQL requests:

('countUnivers1', "SELECT COUNT(*) \
                        FROM ourson_offer o \
                        WHERE o.cat LIKE '1%' \
                        AND CHARACTER_LENGTH(o.cat) = 7"),

like this one.


Solution

  • Text is two dimensional: lines + characters within lines. A "table" is a python string which has new lines in it - it is a text! A new line is started after each line-end characters (CRLF, CR or LF depending on operating system/platform).

    What you would like to do requires understanding the structure of the string as text and vertically aligning new blocks.

    def pad_lines_vertically(lines, size):
        ''' List of lines of exactly `size` length.
        Extended with empty lines if needed.
        '''
        orig_lines = list(lines)
        assert size >= len(orig_lines)
        return orig_lines + [''] * (size - len(orig_lines))
    
    def pad_lines_horizontally(lines):
        ''' Pad lines to the lenght of the longest line.
        '''
        line_length = max(len(line) for line in lines)
        return [
            line.ljust(line_length)
            for line in lines
        ]
    
    def text_add(text1, text2, padding=' '):
        lines1 = text1.splitlines()
        lines2 = text2.splitlines()
        line_count = max(len(lines1), len(lines2))
    
        def pad_lines(lines):
            return pad_lines_horizontally(
                pad_lines_vertically(lines, line_count)
            )
    
        return '\n'.join(
            ''.join(line1 + padding + line2)
            for line1, line2 in zip(pad_lines(lines1), pad_lines(lines2))
        )
    

    Used like this:

    text1 = '''\
    countUnivers1:
    +----------+
    | COUNT(*) |
    +-------
    | 1681943  |
    +----------+
    '''
    
    text2 = '''\
    countUnivers2:
    +----------+
    | COUNT(*) |
    +----------+
    |  51954   |
    +----------+
     plus a
     comment
    '''
    
    print text_add(text1, text2, padding='\t')
    
    
    countUnivers1:  countUnivers2:
    +----------+    +----------+
    | COUNT(*) |    | COUNT(*) |
    +-------        +----------+
    | 1681943  |    |  51954   |
    +----------+    +----------+
                     plus a
                     comment