Table example:
"id","xxx', "xxxx" "xxxx", "dec"
where x = string, id = id, dec = decimal.
It just returns a 1 instead of the correct 274. When I run the query in MySql, the result is correct.
def add_amounts(self):
myTotal = 0
mydb = MySQLdb.connect("localhost", "TomM", "67706621TM", "expenses")
cursor = mydb.cursor()
myTotal = cursor.execute("SELECT SUM(amount) as total FROM all_transactions;")
print(myTotal)
As you didn't tell us the exact table structure, i don't know which criteria you use to summarize the amount.
But you have to use a query like this.
SELECT ColumnName, SUM(amount) as total FROM all_transactions
GROUP BY ColumName;
So you get the sum of the amount for every what ever you have in ColumName .
You are printing the return value of cursor.execute, but the value you want - the result of the SUM - is in the first column of the first row of the resultset.
>>> import MySQLdb
>>> conn = MySQLdb.connect('localhost', 'root', 'secret', 'test')
>>> cursor = conn.cursor()
>>> cursor.execute("""SELECT SUM(assessment) FROM my_table;""")
1
>>> row = cursor.fetchone() # Get the row
>>> result = row[0] # Our result is in the first column of the row.
>>> print(result)
1552.50
I am trying to calculate the mode value of each row and store the value in the judge = judge column, however it updates only the first record and leaves the loop
ps: Analisador is my table and resultado_2 is my db
import sqlite3
import statistics
conn = sqlite3.connect("resultado_2.db")
cursor = conn.cursor()
data = cursor.execute("SELECT Bow, FastText, Glove, Wordvec, Python, juiz, id FROM Analisador")
for x in data:
list = [x[0],x[1],x[2],x[3],x[4],x[5],x[6]]
mode = statistics.mode(list)
try:
cursor.execute(f"UPDATE Analisador SET juiz={mode} where id={row[6]}") #row[6] == id
conn.commit()
except:
print("Error")
conn.close()
You have to fetch your records after SQL is executed:
cursor.execute("SELECT Bow, FastText, Glove, Wordvec, Python, juiz, id FROM Analisador")
data = cursor.fetchall()
That type of SQL query is different from UPDATE (that you're using in your code too) which doesn't need additional step after SQL is executed.
I want to select columns by name specified by user, but I want to avoid SQL Injection.
I think something like that isn't a good idea:
column_one = input("Column one")
column_two = input("Column two")
column_three = input("Column three")
sql.execute("Select {}, {}, {} from table;".format(column_one, column_two, column_three))
I can use something like that:
con = sql.connect("example.sqlite3")
select = "select ? from table;"
t = ('id', )
cur = con.cursor()
cur.execute(selec, t)
rows = cur.fetchall()
con.commit()
con.close()
for row in rows:
for cell in row:
print(cell)
What I get is: id id id id id id id...
Write a query to return all columns from the table, and then select which ones to return using conditional logic.
import sqlite3
#connect to the sqlite database
conn = sqlite3.connect('database.db')
#create a cursor
c = conn.cursor()
#select query to return a single row
c.execute('SELECT NAME FROM T1')
#row contains the returned result
row = c.fetchone()
#print the result
print(row)
It prints something like --> (u'John',), but I only want John
You are printing the whole row, which is always going to be a tuple.
If you wanted to print just the first column, use subscription:
print(row[0])
I'm not asking for the SHOW COLUMNS command.
I want to create an application that works similarly to heidisql, where you can specify an SQL query and when executed, returns a result set with rows and columns representing your query result. The column names in the result set should match your selected columns as defined in your SQL query.
In my Python program (using MySQLdb) my query returns only the row and column results, but not the column names. In the following example the column names would be ext, totalsize, and filecount. The SQL would eventually be external from the program.
The only way I can figure to make this work, is to write my own SQL parser logic to extract the selected column names.
Is there an easy way to get the column names for the provided SQL?
Next I'll need to know how many columns does the query return?
# Python
import MySQLdb
#===================================================================
# connect to mysql
#===================================================================
try:
db = MySQLdb.connect(host="myhost", user="myuser", passwd="mypass",db="mydb")
except MySQLdb.Error, e:
print "Error %d: %s" % (e.args[0], e.args[1])
sys.exit (1)
#===================================================================
# query select from table
#===================================================================
cursor = db.cursor ()
cursor.execute ("""\
select ext,
sum(size) as totalsize,
count(*) as filecount
from fileindex
group by ext
order by totalsize desc;
""")
while (1):
row = cursor.fetchone ()
if row == None:
break
print "%s %s %s\n" % (row[0], row[1], row[2])
cursor.close()
db.close()
cursor.description will give you a tuple of tuples where [0] for each is the column header.
num_fields = len(cursor.description)
field_names = [i[0] for i in cursor.description]
This is the same as thefreeman but more in pythonic way using list and dictionary comprehension
columns = cursor.description
result = [{columns[index][0]:column for index, column in enumerate(value)} for value in cursor.fetchall()]
pprint.pprint(result)
Similar to #James answer, a more pythonic way can be:
fields = [field_md[0] for field_md in cursor.description]
result = [dict(zip(fields,row)) for row in cursor.fetchall()]
You can get a single column with list comprehension over the result:
extensions = [row['ext'] for row in result)
or filter results using an additional if in the list comprehension:
large = [row for row in result if row['filesize'] > 1024 and row['filesize'] < 4096]
or accumulate values for filtered columns:
totalTxtSize = reduce(
lambda x,y: x+y,
filter(lambda x: x['ext'].lower() == 'txt', result)
)
I think this should do what you need (builds on the answer above) . I am sure theres a more pythony way to write it, but you should get the general idea.
cursor.execute(query)
columns = cursor.description
result = []
for value in cursor.fetchall():
tmp = {}
for (index,column) in enumerate(value):
tmp[columns[index][0]] = column
result.append(tmp)
pprint.pprint(result)
You could also use MySQLdb.cursors.DictCursor. This turns your result set into a python list of python dictionaries, although it uses a special cursor, thus technically less portable than the accepted answer. Not sure about speed. Here's the edited original code that uses this.
#!/usr/bin/python -u
import MySQLdb
import MySQLdb.cursors
#===================================================================
# connect to mysql
#===================================================================
try:
db = MySQLdb.connect(host='myhost', user='myuser', passwd='mypass', db='mydb', cursorclass=MySQLdb.cursors.DictCursor)
except MySQLdb.Error, e:
print 'Error %d: %s' % (e.args[0], e.args[1])
sys.exit(1)
#===================================================================
# query select from table
#===================================================================
cursor = db.cursor()
sql = 'SELECT ext, SUM(size) AS totalsize, COUNT(*) AS filecount FROM fileindex GROUP BY ext ORDER BY totalsize DESC;'
cursor.execute(sql)
all_rows = cursor.fetchall()
print len(all_rows) # How many rows are returned.
for row in all_rows: # While loops always make me shudder!
print '%s %s %s\n' % (row['ext'], row['totalsize'], row['filecount'])
cursor.close()
db.close()
Standard dictionary functions apply, for example, len(row[0]) to count the number of columns for the first row, list(row[0]) for a list of column names (for the first row), etc. Hope this helps!
This is only an add-on to the accepted answer:
def get_results(db_cursor):
desc = [d[0] for d in db_cursor.description]
results = [dotdict(dict(zip(desc, res))) for res in db_cursor.fetchall()]
return results
where dotdict is:
class dotdict(dict):
__getattr__ = dict.get
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
This will allow you to access much easier the values by column names.
Suppose you have a user table with columns name and email:
cursor.execute('select * from users')
results = get_results(cursor)
for res in results:
print(res.name, res.email)
Something similar to the proposed solutions, only the result is json with column_header : vaule for db_query ie sql.
cur = conn.cursor()
cur.execute(sql)
res = [dict((cur.description[i][0], value) for i, value in enumerate(row)) for row in cur.fetchall()]
output json example:
[
{
"FIRST_ROW":"Test 11",
"SECOND_ROW":"Test 12",
"THIRD_ROW":"Test 13"
},
{
"FIRST_ROW":"Test 21",
"SECOND_ROW":"Test 22",
"THIRD_ROW":"Test 23"
}
]
Looks like MySQLdb doesn't actually provide a translation for that API call. The relevant C API call is mysql_fetch_fields, and there is no MySQLdb translation for that
Try:
cursor.column_names
mysql connector version:
mysql.connector.__version__
'2.2.9'
You can also do this to just get the field titles:
table = cursor.description
check = 0
for fields in table:
for name in fields:
if check < 1:
print(name),
check +=1
check =0
cursor.column_names is a nice and simple one.
column_names = cursor.field_names
found an easy way of having colums like sql using pymysql and pandas
import pymysql
import pandas as pd
db = pymysql.connect(host="myhost", user="myuser", passwd="mypass", db="mydb")
query = """SELECT ext
SUM(size) as totalsize,
COUNT(*) as filecount
FROM fileindex
GROUP BY ext
ORDER BY totalsize DESC;
"""
df = pd.read_sql_query(query,db)
the DataFrame will have column names ext,totalsize,filecount by default no need to do additional stuff.
for example in my case: