Python Database update from XML only updates last record - python

I have write a script to update stock in my mysql db, but i get only the last record from the xml updated, i'm looking through a tunnel right know and love to have a fresh pair of eyes looking at it.
import requests
import xml.etree.ElementTree as ET
from lxml import etree
from getpass import getpass
from mysql.connector import connect, Error
r = requests.get('http://api.edc.nl/xml/eg_xml_feed_stock.xml')
root = ET.fromstring(r.content)
for x in root.iter('product'):
id = x.find('productid').text
qty = x.find('qty').text
try:
with connect(
host="my host",
user=input("Enter username: "),
database="my database",
password=getpass("Enter password: "),
) as connection:
query = "UPDATE `ps_stock_available` SET `quantity` = " + \
qty + " WHERE `id_product` = " + id + ";"
with connection.cursor() as cursor:
cursor.execute(query)
connection.commit()
#result = cursor.fetchall()
# for row in result:
print(query)
except Error as e:
print(e)

The code that upates the table needs to be inside the for loop. Otherwise it only runs once after the loop completes, and uses the last values of the variables.
query = "UPDATE `ps_stock_available` SET `quantity` = %s WHERE `id_product` = %s"
try:
with connect(
host="my host",
user=input("Enter username: "),
database="my database",
password=getpass("Enter password: "),
) as connection:
with connection.cursor() as cursor:
for x in root.iter('product'):
prod_id = x.find('productid').text
qty = x.find('qty').text
cursor.execute(query, (qty, prod_id))
connection.commit()
except Error as e:
print(e)
Don't use id as a variable, it's the name of a built-in function.

Related

Operational Error when running SQL statements in Python

I am trying to run some SQL statements in a Python environment in Visual Studio Code. The database that I am querying is in MySQL Workbench 8.0. My program runs smoothly until it reaches the querying part. It connects to the database fine. Here is my code:
from gettext import install
import pymysql
con = pymysql.Connect( #Creating connection
host = 'localhost', #
port = 3306, #
user = 'root', #
password = 'Musa2014', #
db = 'referees', #
charset = 'utf8' #
)
Ref_Info = input("Enter referee details: ") #First input statement
Ref_First_Name, Ref_Last_Name, Ref_Level = Ref_Info.split()
Ref_Info_Table = []
RefID = 1 #Setting the value of the RefID
while Ref_Info != '': #Creating loop to get referee information
Ref_Info = Ref_Info.split()
Ref_Info.insert(0, int(RefID))
Ref_Info_Table.append(Ref_Info) #Updating Ref_Info_Table with new referee data
print(Ref_Info_Table) #Printing values #
print(Ref_Info) #
print('Referee ID:', RefID) #
print('Referee First Name:', Ref_First_Name) #
print('Referee Last Name:', Ref_Last_Name) #
print('Referee Level:', Ref_Level) #
Ref_First_Name = Ref_Info[1]
Ref_Last_Name = Ref_Info[2]
Ref_Level = Ref_Info[3]
RefID = RefID + 1 #Increasing the value of RefID
Ref_Info = input("Enter referee details: ") #Establishing recurring input again
cur = con.cursor()
sql_query1 = 'INSERT INTO ref_info VALUES(1, MuhammadMahd, Ansari, B&W)'
sql_query2 = 'SELECT * FROM ref_info'
cur.execute(sql_query1)
cur.execute(sql_query2)
data = cur.fetchall()
con.commit()
cur.close()
con.close()
This is the error that I recieved:
Exception has occurred: OperationalError
(1054, "Unknown column 'MuhammadMahd' in 'field list'")
File "C:\Users\mahd_.vscode\Code Folders\Testing\test2.py", line 44, in
cur.execute(sql_query1)
It would be helpful if you could explain the error and tell me how to resolve it.
Thank you.
The statement in sql_query1
sql_query1 = 'INSERT INTO ref_info VALUES(1, MuhammadMahd, Ansari, B&W)'
miss the " quoting character for string literal; this statement would be sent to your mysql server as
INSERT INTO ref_info VALUES(1, MuhammadMahd, Ansari, B&W)
in which MuhammadMahd and Ansari and B&W do not refer to any column or expression, and are not string literals either. You have to add " to make them string literals:
sql_query1 = 'INSERT INTO ref_info VALUES(1, "MuhammadMahd", "Ansari", "B&W")'
And, to not have to deal to special character escape, you could use python's """ to start and end a string, which is better when you are writing sql in python:
sql_query1 = """INSERT INTO ref_info VALUES(1, "MuhammadMahd", "Ansari", "B&W")"""

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()

Python - SQLite3 - Update not working via input

I try to Update my DB via Input.
import sqlite3
conn = sqlite3.connect('datenbank.db')
print ("Opened database successfully")
kunde1 = input("Der Kundename: ")
anzahl1 = input("Anzahl Bewertung: ")
conn.execute('''UPDATE kundenname SET anzahl = ? WHERE kundename = ?''',
(anzahl1, kunde1))
conn.commit
it dosent Show any Errors.. but it get not updated in DB?
Thanks a lot !
conn.commit does not call commit, rather, it is merely accessing its instance. Therefore, a simple commit call and a file close should fix the problem:
import sqlite3
conn = sqlite3.connect('datenbank.db')
print ("Opened database successfully")
kunde1 = input("Der Kundename: ")
anzahl1 = input("Anzahl Bewertung: ")
conn.execute('''UPDATE kundenname SET anzahl = ? WHERE kundename = ?''', (anzahl1, kunde1))
conn.commit()
conn.close()
since you are inputting data in the middle of the execution sequence, it may be better to use a contextmanager:
import contextlib
#contextlib.contextmanager
def update_database(kunde1, anzahl1):
conn = sqlite3.connect('datenbank.db')
print ("Opened database successfully")
yield conn #can be used later to update database in or outside the scope of "with"
conn.execute('''UPDATE kundenname SET anzahl = ? WHERE kundename = ?''', (anzahl1, kunde1))
conn.commit()
conn.close()
with update_database(input("Der Kundename: "), input("Anzahl Bewertung: ")) as b:
pass #do something after

Python code not creating tables on the database but able to query the results postgres

My usecase is to write create a temp table in the postgres database and fetch records from it and insert into a different table.
The code i used is:
import psycopg2
import sys
import pprint
from __future__ import print_function
from os.path import join,dirname,abspath
import xlrd
import os.path
newlist = []
itemidlist = []
def main():
conn_string = "host='prod-dump.cvv9i14mrv4k.us-east-1.rds.amazonaws.com' dbname='ebdb' user='ebroot' password='*********'"
# print the connection string we will use to connect
# print "Connecting to database" % (conn_string)
# get a connection, if a connect cannot be made an exception will be raised here
conn = psycopg2.connect(conn_string)
# conn.cursor will return a cursor object, you can use this cursor to perform queries
cursor = conn.cursor()
dealer_id = input("Please enter dealer_id: ")
group_id = input("Please enter group_id: ")
scriptpath = os.path.dirname('__file__')
filename = os.path.join(scriptpath, 'Winco - Gusti.xlsx')
xl_workbook = xlrd.open_workbook(filename, "rb")
xl_sheet = xl_workbook.sheet_by_index(0)
print('Sheet Name: %s' % xl_sheet.name)
row=xl_sheet.row(0)
from xlrd.sheet import ctype_text
print('(Column #) type:value')
for idx, cell_obj in enumerate(row):
cell_type_str = ctype_text.get(cell_obj.ctype, 'unknown type')
#print('(%s) %s %s' % (idx, cell_type_str, cell_obj.value))
num_cols = xl_sheet.ncols
for row_idx in range(0, xl_sheet.nrows): # Iterate through rows
num_cols = xl_sheet.ncols
id_obj = xl_sheet.cell(row_idx, 1) # Get cell object by row, col
itemid = id_obj.value
#if itemid not in itemidlist:
itemidlist.append(itemid)
# execute our Query
'''
cursor.execute("""
if not exists(SELECT 1 FROM model_enable AS c WHERE c.name = %s);
BEGIN;
INSERT INTO model_enable (name) VALUES (%s)
END;
""" %(itemid,itemid))
'''
cursor.execute("drop table temp_mbp1")
try:
cursor.execute("SELECT p.model_no, pc.id as PCid, g.id AS GROUPid into public.temp_mbp1 FROM products p, \
model_enable me, products_clients pc, groups g WHERE p.model_no = me.name \
and p.id = pc.product_id and pc.client_id = %s and pc.client_id = g.client_id and g.id = %s"\
% (dealer_id,group_id)
except (Exception, psycopg2.DatabaseError) as error:
print(error)
cursor.execute("select count(*) from public.temp_mbp1")
# retrieve the records from the database
records = cursor.fetchall()
# print out the records using pretty print
# note that the NAMES of the columns are not shown, instead just indexes.
# for most people this isn't very useful so we'll show you how to return
# columns as a dictionary (hash) in the next example.
pprint.pprint(records)
if __name__ == "__main__":
main()
The try except block in between the program is not throwing any error but the table is not getting created in the postgres database as i see in the data admin.
The output shown is:
Please enter dealer_id: 90
Please enter group_id: 13
Sheet Name: Winco Full 8_15_17
(Column #) type:value
[(3263,)]
Thanks,
Santosh
You didn't commit the changes, so they aren't saved in the database. Add to the bottom, just below the pprint statement:
conn.commit()

Python 3 + SQLite check

Hello
I have a question about SQLite functions, maybe.
So, question:
How to check if name I set in Python is in certain column?
Example:
name = 'John'
Table name = my_table
Column name = users
Code details:
C = conn.cursor()
Please
Use parameter in the query as required. See the attached example for better understanding.
Sample SQLite code for searching value in tables
import sqlite3 as sqlite
import sys
conn = sqlite.connect("test.db")
def insert_single_row(name, age):
try:
age = str(age)
with conn:
cursor = conn.cursor()
cursor.execute("CREATE TABLE IF NOT EXISTS USER_TABLE(NAME TEXT, AGE INTEGER);")
cursor.execute("INSERT INTO USER_TABLE(NAME, AGE) VALUES ('"+name+"',"+age+")")
return cursor.lastrowid
except:
raise ValueError('Error occurred in insert_single_row(name, age)')
def get_parameterized_row(name):
try:
with conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM USER_TABLE WHERE NAME = :NAME",
{"NAME":name})
conn.commit()
return cursor.fetchall()
except:
raise ValueError('Error occurred in get_parameterized_row(name)')
if __name__ == '__main__':
try:
return_id = insert_single_row("Shovon", 24)
return_id = insert_single_row("Shovon", 23)
return_id = insert_single_row("Sho", 24)
all_row = get_parameterized_row("Shovon")
for row in all_row:
print(row)
except Exception as e:
print(str(e))
Output:
('Shovon', 24)
('Shovon', 23)
Here I have created a table called USER_TABLE with two attributes: NAME and AGE. Then I inserted several values in the table and searched for a specific NAME. Hope it gives a way to start using SQLite in the project.

Categories

Resources