Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Print results in MySQL format with Python

Tags:

python

mysql

What is the easiest way to print the result from MySQL query in the same way MySQL print them in the console using Python? For example I would like to get something like that:

+---------------------+-----------+---------+
| font                | documents | domains |
+---------------------+-----------+---------+
| arial               |     99854 |    5741 |
| georgia             |     52388 |    1955 |
| verdana             |     43219 |    2388 |
| helvetica neue      |     22179 |    1019 |
| helvetica           |     16753 |    1036 |
| lucida grande       |     15431 |     641 |
| tahoma              |     10038 |     594 |
| trebuchet ms        |      8868 |     417 |
| palatino            |      5794 |     177 |
| lucida sans unicode |      3525 |     116 |
| sans-serif          |      2947 |     216 |
| times new roman     |      2554 |     161 |
| proxima-nova        |      2076 |      36 |
| droid sans          |      1773 |      78 |
| calibri             |      1735 |      64 |
| open sans           |      1479 |      60 |
| segoe ui            |      1273 |      57 |
+---------------------+-----------+---------+
17 rows in set (19.43 sec)

Notice: I don't know the max width for each column a priori, and yet I would like to be able to that without going over the table twice. Should I add to the query length() for each column? How does MySQL do it, in order to not impact severely the memory or processing time?

EDIT

I did not think it was relevant to the question but, this is the query I send:

SELECT font.font as font,count(textfont.textid) as documents, count(DISTINCT td.domain) as domains
FROM textfont 
RIGHT JOIN font
ON textfont.fontid = font.fontid
RIGHT JOIN (
        SELECT text.text as text,url.domain as domain, text.textid as textid 
        FROM text 
        RIGHT JOIN url 
        ON text.texturl = url.urlid) as td 
ON textfont.textid = td.textid
WHERE textfont.fontpriority <= 0 
AND textfont.textlen > 100
GROUP BY font.font 
HAVING documents >= 1000 AND domains >= 10
ORDER BY 2 DESC;

And this is the python code I use:

import MySQLdb as mdb

print "%s\t\t\t%s\t\t%s" % ("font","documents","domains")
res = cur.execute(query , (font_priority,text_len,min_texts,min_domains))
for res in cur.fetchall():
    print "%s\t\t\t%d\t\t%d" % (res[0],res[1],res[2])

But this code produces a messy output due to different widths.

like image 344
zenpoy Avatar asked Jun 02 '12 19:06

zenpoy


People also ask

How do I print SQL data in Python?

Step 1: Connect to database using connect() method. Step 2: Create a command to execute the query using cursor() method. Step 3: And then we have used the fetchAll() method which is stored in rows. Step 4: Print all elements of rows.

What is %s and %D in MySQL?

%d – the argument is treated as an integer, and presented as a (signed) decimal number. %s – the argument is treated as and presented as a string. in your examples, $slug is a string and $this->id is an integer.


1 Answers

There is no need for an external library. The prints out the data with the column names. All lines with the 'columns' variable can be eliminated if you do not need the column names.

sql = "SELECT * FROM someTable"
cursor.execute(sql)
conn.commit()
results = cursor.fetchall()

widths = []
columns = []
tavnit = '|'
separator = '+' 

for cd in cursor.description:
    widths.append(max(cd[2], len(cd[0])))
    columns.append(cd[0])

for w in widths:
    tavnit += " %-"+"%ss |" % (w,)
    separator += '-'*w + '--+'

print(separator)
print(tavnit % tuple(columns))
print(separator)
for row in results:
    print(tavnit % row)
print(separator)

This is the output:

+--------+---------+---------------+------------+------------+
| ip_log | user_id | type_id       | ip_address | time_stamp |
+--------+---------+---------------+------------+------------+
| 227    | 1       | session_login | 10.0.0.2   | 1358760386 |
| 140    | 1       | session_login | 10.0.0.2   | 1358321825 |
| 98     | 1       | session_login | 10.0.0.2   | 1358157588 |
+--------+---------+---------------+------------+------------+

The magic lies in the third column of each cursor.description line (called cd[2] in the code). This column represents the length in characters of the longest value. Thus we size the displayed column as the greater between that and the length of the column header itself (max(cd[2], len(cd[0]))).

like image 141
dotancohen Avatar answered Oct 19 '22 23:10

dotancohen