MySQL UPDATE with Python - python

I am trying to update records from my database named Template, Table clients. I get my updated information from a Tkinter Treeview. I am updating any field except user_id which is my primary key. I get a syntax error on cur.execute(sql_command). cur is define as my cursor.
# Function to Edit Record
def edit_client():
# Update the Database
print(user_id_box.get())
sql_command = ("UPDATE clients SET \
f_name = f_name_box.get(),\
l_name = l_name_box.get(),\
email = email_box.get(),\
phone = phone_box.get(),\
price = price_box.get(),\
address = address_box.get(),\
city = city_box.get(),\
state = state_box.get(),\
country = country_box.get(),\
zipcode = zipcode_box.get() WHERE user_id = user_id_box.get()")
# Execute the SQL command
cur.execute(sql_command)
# Commit the changes to the database
mydb.commit()
# Clear the old entry
clear_record()
# Refresh the Data Frame
query_database()

Note that f_name.get() inside a string like "f_name = f_name.get()" will not work.
For your case, you can use placeholder (%s for MySQL) in SQL statement:
sql_command = f"""UPDATE clients
SET f_name = %s, l_name = %s,
email = %s, phone = %s,
price = %s, address = %s,
city = %s, state = %s,
country = %s, zipcode = %s
WHERE user_id = %s"""
cur.execute(sql_command, (f_name_box.get(), l_name_box.get(),
email_box.get(), phone_box.get(),
price_box.get(), address_box.get(),
city_box.get(), state_box.get(),
country_box.get(), zipcode_box.get(),
user_id_box.get()))

The simplest solution would be using f-string and braces to properly put values inside string. Here I also used docstrings, so you don't need backslashes.
def edit_client():
print(user_id_box.get())
sql_command = f"""UPDATE clients SET
f_name = {f_name_box.get()},
l_name = {l_name_box.get()},
email = {email_box.get()},
phone = {phone_box.get()},
price = {price_box.get()},
address = {address_box.get()},
city = {city_box.get()},
state = {state_box.get()},
country = {country_box.get()},
zipcode = {zipcode_box.get()} WHERE user_id = {user_id_box.get()}"""
cur.execute(sql_command)
mydb.commit()
clear_record()
query_database()
HOWEVER
I do strongly recommend you to sanitise your inputs and pass them as arguments to executor, as SQL injections are still a thing, even if you don't care about security, you can still simply break query, by having broken inputs.
I do not know which library you utilise in order to communicate with DB, but it's documentation should cover it, if it is not from early 1970, created by some student.

Related

keep other mysql entry records while updating other fields just by pressing enter for no new record in python

I am writing a function in python that will update some of the columns in a row of a mysql table. What the function does is it asks for id, then the function shows the record before the update, then asks for user input new values in every column. Within the function, I mentioned "to re enter values that do not need changes". I learned that it is easier to just press enter for fields that do not need updates. But in my current function, when I press enter for fields that do not need an update, it deletes the value.
def update_details(id):
print('Before updating the account details:')
before_update = 'SELECT * FROM cdw_sapp_customer WHERE id = %s'
mycursor.execute(before_update, (id,))
record = mycursor.fetchone()
print(record)
print('\n')
print('Enter the new account details (re-enter detail if no change is necessary):')
first_name = input('Enter the new first name: ').title()
middle_name = input('Enter the new middle name: ').lower()
last_name = input('Enter the new last name: ').title()
street_add_apt = input('Enter the new street address,apartment number(if any): ')
country = input('Enter the new country: ').title()
# I had to put this zip required, because I am having issue when I just pressed enter
zip = int(input('REQUIRED: old or new: Please enter the new zip code: '))
phone = input('Enter the new phone number in xxx-xxxx: ')
email = input('Enter the new email: ')
print('\n')
update = 'UPDATE customer SET FIRST_NAME = %s, MIDDLE_NAME = %s, LAST_NAME = %s, FULL_STREET_ADDRESS = %s, ZIP = %s, PHONE = %s, EMAIL = %s WHERE id = %s'
mycursor.execute(update, (first_name, middle_name, last_name, street_add_apt, country, zip, phone, email, id))
mydb.commit()
# show the new record
after_update = 'SELECT * FROM cdw_sapp_customer WHERE id = %s'
mycursor.execute(after_update, (ssn,))
# record = mycursor.fetchone()
# print(record)
print('\n')
# update the last_updated field in the cdw_sapp_customer table with the date and time of the new details
update_last_updated = 'UPDATE cdw_sapp_customer SET LAST_UPDATED = CURRENT_TIMESTAMP WHERE id = %s'
mycursor.execute(update_last_updated, (id,))
mydb.commit()
print('\n')
print('Updated account details:')
after_update = 'SELECT * FROM customer WHERE id = %s'
mycursor.execute(after_update, (id,))
record = mycursor.fetchone()
print(record)
print('\n')
Initially, the function above, users have to put entries in every question. What I would like to happen is that if the information is the same of any field, they just press enter and when the function returns the line of new record, all other information that does not need to be changed will be the same. From the above function, when I just press enter, it deletes the entry for the field.

python - Error entering data into the database

A new member has been registered in the database, but when entering the profile modification page and adding other information, it is registered in a new row and not in the same information as the registered member.
register new member :
def add_users(self):
add_fullname = self.line_fullname.text()
add_username = self.line_username.text()
add_Email = self.line_email.text()
add_password = self.line_password.text()
add_phone = self.line_telephon.text()
add_birthday = self.dateofbirth.text()
add_profession = self.line_profession.text()
add_Country = self.line_country.text()
add_keyone = self.keyone.text()
add_keytwo = self.keytwo.text()
add_newpassword = self.new_pwd.text()
self.cur.execute(''' SELECT add_username FROM users=add_username''')
data = self.cur.fetchall()
self.cur.execute(''' INSERT INTO users(add_fullname,
add_username, add_Email, add_password, add_phone,
add_birthday, add_profession, add_Country, add_keyone, add_keytwo, add_newpassword)
VALUE (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s ) ''',
(add_fullname, add_username, add_Email, add_password, add_phone, add_birthday,
add_profession, add_Country, add_keyone, add_keytwo, add_newpassword))
self.mysql_db.commit()
self.line_fullname.clear()
self.line_username.clear()
self.line_email.clear()
self.line_password.clear()
this code for fill profile :
def save_profil(self):
self.tabWidget.setCurrentIndex(6)
add_fullname = self.line_fullname.text()
add_Email = self.line_email.text()
add_phone = self.line_telephon.text()
add_birthday = self.dateofbirth.text()
add_profession = self.line_profession.text()
add_Country = self.line_country.text()
add_keyone = self.keyone.text()
add_keytwo = self.keytwo.text()
add_newpassword = self.new_pwd.text()
self.cur.execute(''' INSERT INTO users(add_fullname, add_Email, add_phone, add_birthday, add_profession,
add_Country, add_keyone, add_keytwo, add_newpassword)
VALUE (%s, %s, %s, %s, %s, %s, %s, %s, %s ) ''',
(add_fullname, add_Email,
add_phone, add_birthday, add_profession,
add_Country, add_keyone, add_keytwo, add_newpassword))
self.mysql_db.commit()
print("profil edited")
You should use UPDATE instead of INSERT in the "save_profil" function if the profile already exists.
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
You will also need to indicate which user should be updated in
WHERE condition
I would also advise you to read the user ID or another unique key you have defined in your table. So you can update the correct user.
Ex:
def save_profil(self):
self.tabWidget.setCurrentIndex(6)
add_fullname = self.line_fullname.text()
add_Email = self.line_email.text()
add_phone = self.line_telephon.text()
add_birthday = self.dateofbirth.text()
add_profession = self.line_profession.text()
add_Country = self.line_country.text()
add_keyone = self.keyone.text()
add_keytwo = self.keytwo.text()
add_newpassword = self.new_pwd.text()
query = "UPDATE users SET add_fullname=%s, add_Email=%s, add_phone=%s, add_birthday=%s, add_profession=%s, add_Country=%s, add_keyone=%s, add_keytwo=%s, add_newpassword= %s WHERE (UNIQUE_KEY = %s)"
data = (add_fullname, add_Email,add_phone, add_birthday, add_profession,add_Country, add_keyone, add_keytwo, add_newpassword, UNIQUE_KEY_VALUE)
self.cur.execute(query,data)
self.mysql_db.commit()
print("profil edited")
Note that UNIQUE_KEY and UNIQUE_KEY_VALUE are suggestions, you must define these values according to your model.
As I can see in the figure that shows the database, you can use the "id" to know which user should be updated.For this case, UNIQUE_KEY would be replaced by id, and UNIQUE_KEY_VALUE would be the user id that needs to be updated, in your example it would be 14, but you need to get that value inside your function, just like you got the other values.

Python Executing SQL fails over due to non existing field in json data

I am getting some JSON data from a third party API. I am trying to add that data into my own database to be used for a website. I loop through each record in the JSON and execute a SQL query to insert that data into my database. However some records in the JSON data doesn't exist, and therefore causes my query to fail. I have set defaults for these fields for this reason however it still falls over.
isNonFoilOnly field will only appear in some of of the records in the JSON data.
models.py
class Set(models.Model):
code = models.CharField(max_length=100, unique=True)
keyrune_code = models.CharField(max_length=100)
name = models.CharField(max_length=100)
type = models.CharField(max_length=100)
release_date = models.DateField()
base_set_size = models.IntegerField()
total_set_size = models.IntegerField()
is_online_only = models.BooleanField(default=False)
is_non_foil_only = models.BooleanField(default=False)
is_foil_only = models.BooleanField(default=False)
sale_status = models.BooleanField(default=False)
def __str__(self):
return self.name
views.py
response = requests.request("GET", "https://mtgjson.com/api/v5/SetList.json")
data = response.json()["data"]
sorted_obj = sorted(data, key=lambda k: k['releaseDate'], reverse=False)
sql = """
INSERT INTO dashboard_set
(code, keyrune_code, name, type, release_date, base_set_size, total_set_size, is_online_only, is_non_foil_only, is_foil_only, sale_status)
VALUES
( %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s )
ON CONFLICT (code) DO UPDATE
SET keyrune_code = %s,
name = %s,
type = %s,
release_date = %s,
base_set_size = %s,
total_set_size = %s,
is_online_only = %s,
is_non_foil_only = %s,
is_foil_only = %s;
"""
conn = None
try:
params = config()
conn = psycopg2.connect(**params)
cur = conn.cursor()
for entry in sorted_obj:
cur.execute(sql, (
entry["code"],
entry["keyruneCode"],
entry["name"],
entry["type"],
entry["releaseDate"],
entry["baseSetSize"],
entry["totalSetSize"],
entry["isOnlineOnly"],
entry["isNonFoilOnly"],
entry["isFoilOnly"],
False,
entry["keyruneCode"],
entry["name"],
entry["type"],
entry["releaseDate"],
entry["baseSetSize"],
entry["totalSetSize"],
entry["isOnlineOnly"],
entry["isNonFoilOnly"],
entry["isFoilOnly"]
))
conn.commit()
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
return redirect('dashboard:sets')
You seem to using Django and not using it at the same time. The Django way to do this is:
from yourapp.models import Set
def yourview(request):
response = requests.request("GET", "https://mtgjson.com/api/v5/SetList.json")
data = response.json()["data"]
# Not caring about sort, because why?
for entry in data:
code = data.pop('code', None)
if not code:
continue # or raise
Set.objects.update_or_create(code=code, defaults=data)
return redirect('dashboard:sets')

Iterating through MySQL table and updating

I have a MySQL table which stores a couple thousands addresses. I need to parse them to geolocation API, get latitude and longitude and then put them back into corresponding address row (I made special columns for that). The question is what is the most efficient way to do it? Currently I am using python with mysql.connector and geopy for geolocations. So there is a simple code I use for geocoding:
cursor = conn.cursor()
cursor.execute("SELECT description FROM contacts WHERE kind = 'Home adress'")
row = cursor.fetchone()
while row is not None:
geocoded = geolocator.geocode(row, exactly_one=True)
if geocoded is not None:
lat = geocoded.latitude
lon = geocoded.longitude
row = cursor.fetchone()
You can use cursor.executemany() to update the table in one go. This requires that a list of update parameters be created which can then be passed to executemany(). The parameter list can be created from the results of the initial SELECT query. In the example below I have assumed that there is some primary key named key_id for the contacts table:
cursor = conn.cursor()
cursor.execute("SELECT key_id, description FROM contacts WHERE kind = 'Home adress'")
update_params = []
for key_id, description in cursor:
geocoded = geolocator.geocode(description, exactly_one=True)
if geocoded is not None:
lat = geocoded.latitude
lon = geocoded.longitude
update_params.append((lat, lon, key_id))
c.executemany("update contacts set lat = %s, lon = %s where key_id = %s", update_params)
As mentioned above this assumes existence of a primary key. If there is not one and description is a unique field in the table then you could use that. Just remove key_id from the SELECT query, and replace key_id with the description field for both the update_params list and the update query.
#mhavke, thanks a lot! Just what I needed. Here is a finally working code (I made some adjustments). Also I am aware that using '%s' is unsafe, but this goes for internal use only, so not really worried about it.
cursor = conn.cursor()
cursor.execute("SELECT key_id, description FROM contacts WHERE kind = 'Home address'")
update_params = []
for key_id, description in cursor:
geocoded = geolocator.geocode(description, exactly_one=True)
if geocoded is not None:
lat = geocoded.latitude
lon = geocoded.longitude
update_params.append((lat, lon, key_id))
cursor.executemany("update contacts set latitude = %s, longitude = %s where key_id = %s", update_params)
conn.commit()

Python- SQL update operation; no errors but doesn't actually update my database

Im using python and SQL to make a database for customer accounts. I am trying to give the option to update a customer's details. I have done what I believe would update the table but when I print the contents nothing has changed. Please can you tell me where I am going wrong?
def update_Customer(self):
# create sqlite connection
conn = sqlite3.connect("lanyard.db", timeout=5)
c = conn.cursor()
# if texfield is empty
if self.TextField1.get() !="":
if self.TextField2.get() != "":
nameChange1 = self.TextField2.get()
CusNo = self.TextField1.get()
c.execute("""
UPDATE customer
SET first_name = 'nameChange1'
WHERE customer_id = 'CusNo'""")
conn.commit()
if self.TextField3.get() != "":
nameChange2 = self.TextField3.get()
CusNo = self.TextField1.get()
c.execute("""
UPDATE CUSTOMER
SET second_name = 'nameChange2'
WHERE customer_id = 'CusNo'""")
conn.commit()
if self.TextField4.get() == "":
nameChange3 = self.TextField4.get()
CusNo = self.TextField1.get()
c.execute("""
UPDATE CUSTOMER
SET address = 'nameChange3'
WHERE customer_id = 'CusNo'""")
conn.commit()
conn.commit()
c.close()
# clear input
self.TextField1.delete(0, END)
self.TextField2.delete(0, END)
self.TextField3.delete(0, END)
self.TextField4.delete(0, END)
You forgot parameters:
nameChange1 = self.TextField2.get()
CusNo = self.TextField1.get()
c.execute("""
UPDATE customer
SET first_name = ?
WHERE customer_id = ?""", (nameChange1, CusNo,) )
The code is not complete. The class, I am assuming has CREATE TABLE function.
Additionally, look at return value of
c.execute

Categories

Resources