Using DESC within MAX ID Sqlite3 - Python - python

Can someone tell me why the code below is throwing errors. Its meant to look at the current id and if its less the max to descend to the next row in the database and print it.
def loadData(self):
connection = sqlite3.connect('films.db')
c = connection.cursor()
maxid_before = c.execute("SELECT * FROM FILMS WHERE ID = (SELECT MAX(ID) FROM FILMS)")
last_row = maxid_before.fetchone()[0]
maxid_after = c.execute("SELECT * FROM FILMS WHERE ID < (last_row) ORDER BY ID DESC LIMIT 1;").fetchone()
print(maxid_after)
UPDATE
This is the function that calls loadData.What silly mistake have i done this time.You can ignore the first 5 lines or so.
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.edit_btn.clicked.connect(self.Retrieve)
self.edit_save_btn.clicked.connect(self.insertData)
last_id = 0
if not last_id:
connection = sqlite3.connect('films.db')
c = connection.cursor()
result = c.execute("SELECT * FROM FILMS WHERE ID = (SELECT MAX(ID) FROM FILMS)")
last_id = result.fetchone()[0]
self.edit_load_btn.clicked.connect(self.loadData)
And this is the loadData function
def loadData(self, last_id):
connection = sqlite3.connect('films.db')
c = connection.cursor()
maxid_after = c.execute("SELECT * FROM FILMS WHERE ID < ? ORDER BY ID DESC LIMIT 1;", (last_id,)).fetchone()
print(maxid_after)
return maxid_after

Try this -
maxid_after = c.execute("SELECT * FROM FILMS WHERE ID < ? ORDER BY ID DESC LIMIT 1;", (last_row,)).fetchone()
In your code last_row is a variable not column name. So, you should put the value of last_row in the query.
If you put last_row in the query like you did, sqlite will treat last_row as a column name and try to execute the query like that. As it fails to find any column by that name, it throws the error.
If you want to run this function on a button click and return one by one row in descending order in every button click, then your function should be like this -
def loadData(self):
connection = sqlite3.connect('films.db')
c = connection.cursor()
result = c.execute("SELECT * FROM FILMS WHERE ID < ? ORDER BY ID DESC LIMIT 1;", (last_id,)).fetchone()
if result:
self.last_id = result[0]
connection.close()
And the function that calls loadData() should be like -
# This is the code that calls loadData()
# This is __init__
result = c.execute("SELECT * FROM FILMS WHERE ID = (SELECT MAX(ID) FROM FILMS)").fetchone()
if result:
self.last_id = result[0]
...
# On button click
# Call loadData

Related

how to assign variable value with condition

I am work with python. I have code like this :
def return_auth_notificatio():
shiporderid = all_Orderid
cursor.execute("select *from return_auth_notification")
email_record = cursor.fetchall()
for row in email_record:
Orderid = row[1]
Customercomment =row[4]
Amountreturn =row[5]
condition_return_auth_notificatio=(Customercomment,Amountreturn if shiporderid == Orderid else None)
assign_return_auth_notificatio=(condition_return_auth_notificatio if !Null )
return(assign_return_auth_notificatio)
data=return_auth_notificatio()
all_Customercomment=data[0]
all_Amountreurn=data[1]
I want this variable Customercomment,Amountreturn if records whose Orderid matches all_Orderid
Put the condition in the query instead of the loop.
def return_auth_notificatio():
customer_comments = []
amount_returns = []
cursor.execute("""
select Customercomment, Amountreturn
from return_auth_notification
WHERE Orderid = %s""", (all_Orderid,))
for comment, amount in cursor.fetchall():
customer_comments.append(comment)
amount_returns.append(amount)
return customer_comments, amount_returns
all_Customercomment, all_Amountreturn = return_auth_notificatio()
The placeholder %s assumes you're using MySQL. If it's SQLite use ? instead.

Why wont this loop?

Newby working my way through python and sql with mariadb.
Why wont this loop? It updates the first record only. Im pretty hack at this...
cursor1.execute("select recordid, mvavgvol, quote_usd_volume_change_24h from pumped")
records = cursor1.fetchall()
for x in records:
rid = (x[0])
m = (x[1])
o = (x[2])
if (m >= o):
result = 0
else:
result = 1
upd_data=(result,rid)
sql1 = ("UPDATE pumped SET mvavgvolcheck = %s WHERE recordid = %s")
cursor2.execute(sql1,upd_data)
conn.commit()
Since you are fetching multiple rows you have to store the fetched values in an array and use cursor's executemany() method instead.
✂
data= []
for x in records:
rid = (x[0])
result= int(x[1] > x[2])
data+= [(result, rid)]
cursor.executemany(UPDATE pumped SET mvavgvolcheck = %s WHERE recordid = %s", data);
✂
When using mariadb python module (MariaDB Connector/Python) this is much more effective since it reduces network traffic: instead of sending n update commands in a loop (where n is the number of rows in table pumped) only one command will be send to the server.
conn = msql.connect(host=Host,port=Port, user=User, password=Password, database=database)
cursor1 = conn.cursor()
cursor2 = conn.cursor()
cursor1.execute("select recordid, mvavgvol, quote_usd_volume_change_24h from pumped")
records = cursor1.fetchall()
for x in records:
rid = (x[0])
m = (x[1])
o = (x[2])
if (m >= o):
result = 0
cursor2.execute("UPDATE pumped SET mvavgvolcheck = %s WHERE recordid = %s",(result, rid))
conn.commit()
else:
result = 1
cursor2.execute("UPDATE pumped SET mvavgvolcheck = %s WHERE recordid = %s",(result, rid))
conn.commit()

MySQL update or insert based on fetchall results in Python

I need to set some user meta in my wordpress through local python script. Hence I can't use the WP update_user_meta for it - it has to be done manually.
import mysql.connector as mysql
cnx = mysql.connect(host=HOST, database=DATABASE, user=USER, password=PASSWORD)
cursor = cnx.cursor()
get_meta = ("SELECT * FROM `ff_usermeta` WHERE `user_id`= 1 AND (`meta_key`='nickname' OR `meta_key`='info' OR `meta_key`='bg' OR `meta_key`='avatar' OR `meta_key`='profile_updated')")
cursor.execute(get_meta)
meta = cursor.fetchall()
#some processing of the result
cursor.execute(q, (...))
cnx.commit()
cursor.close()
cnx.close()
Now I need to check if the result has meta with each of the keys.
If the key already exists for this user, it needs to run UPDATE for this meta.
If this user still has no meta of this key, it has to INSERT new row.
if(there's no 'nickname' in meta_key on either of 5 or less rows):
q = ("INSERT INTO `ff_usermeta` ...")
else:
q = ("UPDATE `ff_usermeta` ...")
...and 4 more times like that?.. Seems like a good place for a cycle, but I don't really like the idea to make it 5x queues, especially since there might be more fields in the future.
I was thinking along the lines of searching the fetchall result for matches in meta_key, and if found, adding required data to one array, if not - to another. And then just running one update and one insert at the end, assuming both are not empty. If I were to write it in semi-php style, it would look roughly like this:
if(in_array("nickname", meta))
for_update .= "`nickname`='"+data[0]+"', "
else:
fields .= "`nickname`, "
vals .= "'"+data[0]+"', "
if(in_array("bg", meta)):
for_update .= "`bg`='"+data[1]+"', "
else:
fields .= "`bg`, "
vals .= "'"+data[1]+"', "
if(for_update):
update = ("UPDATE `ff_usermeta` SET "+for_update+" WHERE 1")
if(fields):
insert = ("INSERT INTO `ff_usermeta`("+fields+") VALUES ("+vals+")")
But absolutely no clue how to translate it correctly to python. I had to google it up to things like "why dot not working to add one string to another". Any advice? Or perhaps there is a better way? Thanks!
It is not complete, you can not update your rows in that way.
But with this you can start to make your query
The frist select gets exactly 1 row, if the user_id exists.
The user_id doesn't seem the right choice for this, but to get what you can do it is enough.
If the query doesn't have an entry, the it will insert some data you get from anywhere
The update as the insert are in that form wrong as you have to insert 5 new orws or update max 5 rows, but that is more for you to programm
import mysql.connector as mysql
HOST = "localhost"
DATABASE = ""
USER = "root"
PASSWORD = "mypassword"
cnx = mysql.connect(host=HOST, database=DATABASE, user=USER, password=PASSWORD)
cnx = mysql.connect(host=HOST, database=DATABASE, user=USER, password=PASSWORD)
cursor = cnx.cursor()
user_id = 1
get_meta = ("""SELECT umeta_id, user_id , MAX(IF( `meta_key`='nickname', meta_value,'')) AS 'nickname' , MAX(IF( `meta_key`='info', meta_value,'')) AS 'info' , MAX(IF( `meta_key`='bg', meta_value,'')) AS 'bg' , MAX(IF( `meta_key`='avatar', meta_value,''NULL'')) AS 'avatar' , MAX(IF (`meta_key`='profile_updated', meta_value,'')) AS 'profile_updated' FROM `ff_usermeta` WHERE `user_id`= %s GROUP BY umeta_id, user_id:""")
result = cursor.execute(get_meta,(user_id,))
if result > 0:
data = cursor.fetchone()
for_update = "";
#some processing of the result
if not data["nickname"]:
for_update += "`nickname`='"+data["nickname"]+"', "
if not data["bg"]:
for_update += "`bg`='"+data["bg"]+"', "
query = ("UPDATE `ff_usermeta` SET "+for_update+" WHERE user_id = " + user_id)
else:
#here are no data to be gathered as there is no user_id present add new user
nickname = ""
bg= ""
info = ""
avatar = ""
profile_updated = ""
fields= ""
vals = ""
fields += "`nickname`,`info`, `bg`,`avatar`,`profile_updated`"
vals += "'"+nickname+"', "+"'"+info+"', "+"'"+bg+"', "+"'"+avatar+"', "+"'"+profile_updatedfo+"'"
query = ("INSERT INTO `ff_usermeta`("+fields+") VALUES ("+vals+")")
cursor.execute(query)
cnx.commit()
cursor.close()
cnx.close()
I tried my best to adapt the suggestion above, but couldn't figure out how to make it work. Eventually I went another way, and it seems to work somehow, so I'll post the full code in case anyone would find it useful.
What it does: checks the queue in table with validation request, then parses a page (separate function) and updates user profile accodringly.
import mysql.connector as mysql
import time
from datetime import datetime
cnx = mysql.connect(host=HOST, database=DATABASE, user=USER, password=PASSWORD)
while True: #endless loop as a temporary scheduler
cursor = cnx.cursor()
#getting first request in the queue - 0: id, 1: url, 2: parse, 3: status, 4: user, 5: user_page, 6: req_date, 7: action
cursor.execute("SELECT * FROM `ff_qq` WHERE status = 0 LIMIT 1")
row = cursor.fetchone()
if row:
status = 1 #processed
if row[7] == "verify":
get_user = ("SELECT * FROM `ff_users` WHERE ID = %s LIMIT 1")
cursor.execute(get_user, (row[4],))
user = cursor.fetchone() #0 - ID, 5 - user_url, 8 - user_status, 9 - display_name
#separate function that returns data to insert into mysql
udata = verify(row) #0 - nickname, 1 - fb_av, 2 - fb_bg, 3 - fb_info, 4 - owner
ustat = row[1].split("/authors/")
if udata['owned'] or user[8] == ustat[1]:
update_user = ("UPDATE `ff_users` SET user_status = %s, display_name = %s, user_url = %s WHERE ID = %s LIMIT 1")
cursor.execute(update_user, (ustat[1], udata['nickname'], row[1], user[0]))
status = 2 #success
get = ("SELECT `meta_value` FROM `ff_usermeta` WHERE `user_id`= %s AND `meta_key`='ff_capabilities' LIMIT 1")
cursor.execute(get, (row[4],))
rights = cursor.fetchone()
if rights == 'a:1:{s:10:"subscriber";b:1;}':
promote = ("UPDATE `ff_usermeta` SET `meta_value` = 'a:1:{s:6:\"author\";b:1;}' "
"WHERE `user_id` = %s AND `meta_key`='ff_capabilities' LIMIT 1")
cursor.execute(promote, (row[0],))
#list of meta_key values in same order as returned data
ff = ['nickname', 'fb_av', 'fb_bg', 'fb_info']
for x in range(0,3): #goes through each one of the above list
if udata[ff[x]]: #yes this actually works, who would've thought?..
#current meta_key added directly into the string
get = ("SELECT `meta_value` FROM `ff_usermeta` WHERE `user_id`= %s AND `meta_key`='" + ff[x] + "' LIMIT 1")
cursor.execute(get, (row[4],))
meta = cursor.fetchone()
if(meta): #update if it exists, otherwise insert new row
qq = ("UPDATE `ff_usermeta` SET `meta_value` = %s "
"WHERE `user_id` = %s AND `meta_key`='" + ff[x] + "' LIMIT 1")
else:
qq = ("INSERT INTO `ff_usermeta`(`meta_value`, `meta_key`, `user_id`) "
"VALUES ('%s','" + ff[x] + "','%s'")
cursor.execute(qq, (udata[ff[x]], row[0])) #same execute works for both
else:
status = 3 #verification failed
#update queue to reflect its status
update = ("UPDATE `ff_qq` SET status = %s WHERE id = %s LIMIT 1")
cursor.execute(update, (status, row[0]))
cnx.commit()
cursor.close()
now = datetime.now()
print(now.strftime("%d.%m.%Y %H:%M:%S"))
time.sleep(180) #sleep until it's time to re-check the queue
cnx.close()

Convert SQLITE 'NoneType in a int python

I'm trying to "SELECT" a value from Db and add this value to another variable, but when I execute this I get this error "TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' "
id = input("Digite o id do cartão: ")
cash = int(input("Digite o o valor a ser creditado: "))
dia = 3
sql = 'SELECT saldo FROM carteira where idcartao = ?'
def selectbanco():
c.execute("SELECT saldo FROM carteira WHERE idcartao=?", (id,))
row = c.fetchone()
print(row)
row = c.fetchone()
soma = (row) + (cash)
c.execute("UPDATE carteira SET saldo=? WHERE idcartao=?", (soma, id))
connection.commit()
selectbanco()
THIS IS MY COMPLETE CODE
import sqlite3
connection = sqlite3.connect('clientes.db')
c = connection.cursor()
#criação de tabela
def create_table():
c.execute('CREATE TABLE IF NOT EXISTS carteira (idcartao REAL, saldo REAL, data text)')
create_table()
#variaveis
id = input("Digite o id do cartão: ")
cash = int(input("Digite o o valor a ser creditado: "))
dia = 3
sql = 'SELECT saldo FROM carteira where idcartao = ?'
#SELECT E RETORNAR VALOR
def selectbanco():
c.execute("SELECT saldo FROM carteira WHERE idcartao=?", (id,))
row = c.fetchone()
print(row)
row = c.fetchone()
##soma = (row + cash)
##print(soma)
c.execute("UPDATE carteira SET saldo=? WHERE idcartao=?", (cash, id))
connection.commit()
selectbanco()
#leitura do banco
def read_data(wordUsed):
for row in c.execute(sql, (wordUsed,)):
print (row)
read_data(id)
connection.close()
You've got two issues here.
The first is that you exhaust your generator by calling row = c.fetchone() twice, without re-executing the query. You can only iterate through your cursor once for each query result; after that, you will need to re-run the query to "refresh" the data and be able to iterate again.
Second, fetchone() will actually return None if you get no matches. This is in contrast to fetchall() that will instead return an empty list ([]) in the case of no matches.
This quick example should illustrate this behaviour:
import sqlite3
# Create a fake database
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS some_table(
something TEXT
)""")
c.execute(""" INSERT INTO some_table VALUES('hello') """)
c.execute("SELECT * FROM some_table")
# We get a match and this will print '(hello,)'
data = c.fetchone()
print(data)
data = c.fetchone()
# If we don't execute the query again but try to use the exhausted generator
# then we'll also get None
print(data)
c.execute("SELECT * FROM some_table WHERE something = 'bye'")
# This will print 'None' because fetchone() didn't get a result
data = c.fetchone()
print(data)
c.execute("SELECT * FROM some_table WHERE something = 'bye'")
# This will print an empty list because fetchall() didn't get a result
data = c.fetchall()
print(data)
c.close()
conn.close()
Even though None and [] are different, they are still falsey so, in the context of your question, you can still convert either response to an integer:
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute("""create table if not exists some_table(
something TEXT
)""")
c.execute(""" INSERT INTO some_table VALUES('hello') """)
# Get back None or an integer
c.execute(""" SELECT * FROM some_table WHERE something = ?""", ('bye', ))
data = c.fetchone() or 1 # This is where you return an integer instead of None
print(data)
c.close()
conn.close()
I've picked an integer value of 1, maybe you want 0, I'm not sure. The thing to note, though, is that there's two avenues for you to get None or falsey data here, and you're treating them both the same, which isn't great for clarity of code.
You are fetching row twice. You need to remove the second fetch to receive the row.
def selectbanco():
c.execute("SELECT saldo FROM carteira WHERE idcartao=?", (id,))
row = c.fetchone()
print(row)
soma = (row) + (cash)
c.execute("UPDATE carteira SET saldo=? WHERE idcartao=?", (soma, id))
connection.commit()
selectbanco()
The variable gets overwritten because you do not specify a command to execute before fetching (the second time), hence the NoneType.

Python + SQLite3 parameters failing

The parameters on the last cur.execute statement aren't working.
The below code doesn't error out but cur.fetchone() return rows of value (0,) when they shouldn't
with conn:
flag = 0
today = (datetime.date.today() - datetime.timedelta(20)).strftime("%Y-%m-%d")
prev_prev_day = (datetime.date.today() - datetime.timedelta(22)).strftime("%Y-%m-%d")
cur = conn.cursor()
cur.execute("SELECT EXISTS(SELECT user, COUNT(user) cnt FROM logins GROUP BY user HAVING cnt > 1)")
if cur.fetchone()[0] == 1:
flag + 1
cur.execute("SELECT user, COUNT(user) cnt FROM logins GROUP BY user HAVING cnt > 1")
for item in cur.fetchall():
variables = (item[0], today, prev_prev_day,)
# problem in with this statement
cur.execute("SELECT COUNT(*) FROM logins WHERE user = ? AND seen_date BETWEEN ? AND ?", variables)
print cur.fetchone()
I get the right results with:
cur.execute("SELECT COUNT(*) FROM logins WHERE user = ? AND seen_date BETWEEN '2015-07-11' AND '2015-07-13'", variables)
...while only inserting the user = ? variable.
Update: Simply switch your between parameters.
This:
variables = (item[0], today, prev_prev_day,)
Should be:
variables = (item[0], prev_prev_day, today)

Categories

Resources