I have been trying to return the values from two different tables, but can't seem to get the c.execute(query) function to return what I want it to. Currently my code will return the first c.fetchone()[0], but the second fetchone()[5] gives an error that it's out of range, which means it is probably still trying to get data from my 'clients' table which does not have 6 columns. I don't think I fully understand how MySQLdb works it's magic, but can't find any good examples of multi-table queries. Here is my code snippet below! Thanks!
c, conn = connection()
#check if already exists
x = c.execute("SELECT * FROM clients WHERE email = (%s)", (thwart(email),))
if int(x) > 0:
flash("That email already has an account, please try a new email or sign in.")
return render_template('register.html', form=form)
else:
c.execute("INSERT INTO clients (email, phone, password) VALUES (%s, %s, %s)", (thwart(email), thwart(phone), thwart(password)))
c.execute("SELECT cid FROM clients WHERE email = (%s)", (thwart(email),))
clientcid = c.fetchone()[0]
c.execute("INSERT INTO cpersonals (first_name, last_name, address, zip) VALUES (%s, %s, %s, %s)", (thwart(first_name), thwart(last_name), thwart(address), czip))
c.execute("SELECT reg_date FROM cpersonals WHERE cid = (%s)", (clientcid,))
reg_date = c.fetchone()[5]
rating = c.execute("SELECT rating FROM clients WHERE email = (%s)", (thwart(email),))
conn.commit()
flash("Thanks for registering!")
c.close()
conn.close()
Your query is SELECT reg_date FROM cpersonals .... You are only selecting one column. The reason fetchone()[5] fails is, there is no 6th column in the fetched record. Try 0 in place of 5.
Why were you using 5?
Related
I'm using snscrape to scrape instagram. snscrape returns the data in tuple format but it creates the instagram data in a nested tuple. eg.
for b in enumerate(sninstagram.InstagramUserScraper(username='houston_2731').get_items()):
print[(b)]
output
(0, InstagramPost(url='https://www.instagram.com/p/CUdFfjEImHN/', date=datetime.datetime(2021, 9, 30, 17, 39, 20, tzinfo=datetime.timezone.utc), content='"Hardwork plus patience. A symbol of my sacrifice I\'m doing waiting." Nipsey Hussle \n\nIt\'s hard to believe what 5 months and a disciplined diet and hitting the gym hard can do. The first pic in the collage is me at a challenging point in my life. Depression and what not but I had to snap out of it and get in the gym and do the work. As I continue to embark on this fitness journey. I hope to inspire some to join me on this journey. \n\n#fitness #weightloss #muscles #gymmotivation #gymrat #intermittentfasting #fitnessmotivation #fitnessjourney #tenpercentbodyfat #shredded #fitnessgoals #hardwork #patience #discipline #dedication #hunger', thumbnailUrl='https://instagram.fjnb12-1.fna.fbcdn.net/v/t51.2885-15/243385646_584565779558058_6508985384396360110_n.webp?stp=dst-jpg_e35_s640x640_sh0.08&_nc_ht=instagram.fjnb12-1.fna.fbcdn.net&_nc_cat=106&_nc_ohc=nrtaOwxdg64AX8NQE-Z&edm=ABfd0MgBAAAA&ccb=7-4&oh=00_AT_xE-O75IP4MezdzoHM_WxAgbXiivb3aBFUMopAkxxJSA&oe=621D237E&_nc_sid=7bff83', displayUrl='https://instagram.fjnb12-1.fna.fbcdn.net/v/t51.2885-15/243385646_584565779558058_6508985384396360110_n.webp?stp=dst-jpg_e35&_nc_ht=instagram.fjnb12-1.fna.fbcdn.net&_nc_cat=106&_nc_ohc=nrtaOwxdg64AX8NQE-Z&edm=ABfd0MgBAAAA&ccb=7-4&oh=00_AT8JXpM2XKqA_d06LV10Qy_Jt1GYnvpjUEeVZZMRIdwgnQ&oe=621D237E&_nc_sid=7bff83', username='houston_2731', likes=1, comments=0, commentsDisabled=False, isVideo=False))
Now for this reason specifically this output cannot be inserted into the database because it creates a value error caused by the nested tuple because of its type. the database doesn't recognize its type and then fails. so now what I want to do is extract the nested tuple and use it as the main tuple. How do I go about doing that?
class insta():
def instagram(self):
dbname = '******'
user = '******'
password = '******'
host = '******'
port = ****
cur = None
conn = None
try:
conn = psycopg2.connect(
dbname = dbname,
user = user,
password = password,
host = host,
port = port
)
cur = conn.cursor()
cur.execute('DROP TABLE IF EXISTS Machine_instagram')
create_table = '''CREATE TABLE IF NOT EXISTS Machine_instagram (
id serial PRIMARY KEY,
url char,
date timestamp,
content char,
thumbnailUrl char,
displayUrl char,
username char,
likes int,
comments int,
commentsDisabled bool,
isVideo bool)'''
cur.execute(create_table)
for b in enumerate(sninstagram.InstagramUserScraper(username='houston_2731').get_items()):
insert_insta = 'INSERT INTO Machine_instagram (url, date, content,thumbnailUrl, displayUrl, username, likes, comments, commentsDisabled, isVideo) VALUES (%s, %s, %s, %s,%s, %s, %s, %s, %s, %s)'
insert_values = [(b)]
for records in insert_values:
cur.execute(insert_insta, records)
conn.commit()
print('completed')
except Exception as error:
print(error)
finally:
if cur is not None:
cur.close()
if conn is not None:
conn.close()
insta1 = insta()
insta1.instagram()
I have a python function which should execute 2 SQL queries. I have found that it is impossible to execute 2 queries in one command at once, so as a workaround I created a list of my queries and try to iterate over it with execute command. However nothing is added to MySQL table. Here is the code:
#app.route('/addComment', methods=['POST'])
def addComment():
try:
if session.get('user'):
_description = request.form['description']
_user = session.get('user')
_term_id = request.form['termID']
_time = datetime.now()
operation = ['"INSERT INTO comments (description, user, termID, time) VALUES (%s, %s, %s, %s)", (_description, _user, _term_id, _time)', '"INSERT INTO history (user, term, time) VALUES (%s, %s, %s)", (_user, _term_id, _time)']
conn = mysql.connect()
cursor = conn.cursor()
for item in operation:
cursor.execute()
conn.commit()
data = cursor.fetchall()
if len(data) == 0:
conn.commit()
return json.dumps({'status':'OK'})
else:
return json.dumps({'status':'ERROR'})
except Exception as e:
return json.dumps({'status':'Unauthorized access'})
finally:
cursor.close()
conn.close()
Could you please help me?
Errors in your code lies in the following areas:
A. On iteration sql statement is not passed to execute()
Should be:
for item in operation:
cursor.execute(item)
conn.commit()
B. Invalid parameterization
'"INSERT INTO comments (description, user, termID, time) VALUES (%s, %s, %s, %s)", (_description, _user, _term_id, _time)'
This string statement doesn't apply variables to SQL statement string. Depending on your value types you should decide whether to add ' (apostrophe) or not. More safely would be to pass parameters to .execute() function. Example below.
cursor.execute(
"INSERT INTO comments (description, user, termID, time) VALUES (:description, :user, :term_id, :time)",
description=_description,
user=_user,
term_id=_term_id,
time=_time
)
For my school project I decided to make a physics revision tool. The tool lets users log in and saves information about their performance on certain questions. As a result of this I realised I needed to name each table used to store each individual users scores so I thought using .format would be appropriate. It seemed to be working fine until the point where i needed to add code that would add information to the table. From the testing i have done on the code so far, i think the problem is because i am using .format it won't actually create any columns. I don't know how to get around that please help. Appropriate sections of code have been provided:
def quesprep():
intro.destroy()
con= sqlite3.connect("login.db")
c= con.cursor()
c.execute("SELECT accid FROM credentials WHERE accountname = ?", (user,))
global results
results=c.fetchall()
con.commit()
con.close()
con= sqlite3.connect("store.db")
c= con.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS {}(mod integer, ques integer,score integer)""".format(results))
c.execute("INSERT INTO {} Values(mod=2,ques=1, score=0)".format(results))
con.commit()
con.close()
ques()
def mod2q1page():
questionspage.destroy()
con= sqlite3.connect("login.db")
c= con.cursor()
c.execute("SELECT accid FROM credentials WHERE accountname = ?", (user,))
global results
results=c.fetchall()
con.commit()
con= sqlite3.connect("store.db")
c= con.cursor()
c.execute("INSERT OR IGNORE INTO {} VALUES(mod=2, ques=2, score=0)" .format(results))
There seems to be several things wrong here.
Format takes a variable inside the {} ... like {0}, {1} etc
Placeholders are the preferred route to take with formatting sql queries ... like you did in your SELECT
I am not sure what the issue is here but if you are trying to add columns, you need to ALTER the table ... not INSERT. INSERT will add a row item. If you can post the error, perhaps we can help a little more. To start you out though, try placeholders in lieu of format.
Also, fetchall returns a list of tuples ... need to send a tuple in sql, not a list.
for x in results:
c.execute("INSERT INTO ? (col1, col2, col3) VALUES (1, 2, 3);", x)
Edit:
I stand corrected - I ran this code:
data = [('user',)]
cursor.execute("INSERT INTO ? (id, email, password) VALUES (1, test, test);", data)
syntax error because you cannot add placeholder to table name. Read here
I used format with the {0}:
cursor.execute("INSERT INTO {0} (id, email, password) VALUES (1, test, test);".format('user'))
The query was successful. I believe that is your problem here.
found a solution:
intro.destroy()
con= sqlite3.connect("login.db")
c= con.cursor()
c.execute("SELECT accountname FROM credentials WHERE accountname = ?", (user,))
results=c.fetchone()
global tablename
tablename=" ".join(map(str, (results)))
con.commit()
con.close()
global m
m="mod"
global q
q="ques"
global s
s="score"
fieldtype="INTEGER"
con=sqlite3.connect("store.db")
c=con.cursor()
c.execute('CREATE TABLE IF NOT EXISTS {} ({fc} {ft}, {sc} {ft2}, {tc} {ft3})'\
.format(tablename, fc=m, ft=fieldtype, sc=q, ft2=fieldtype, tc=s,
ft3=fieldtype))
con.commit()
con.close()
I HAVE ADDED MY OWN ANSWER THAT WORKS BUT OPEN TO IMPROVEMENTS
After seeing a project at datanitro. I took on getting a connection to MySQL (they use SQLite) and I was able to import a small test table into Excel from MySQL.
Inserting new updated data from the Excel sheet was this next task and so far I can get one row to work like so...
import MySQLdb
db = MySQLdb.connect("xxx","xxx","xxx","xxx")
c = db.cursor()
c.execute("""INSERT INTO users (id, username, password, userid, fname, lname)
VALUES (%s, %s, %s, %s, %s, %s);""",
(Cell(5,1).value,Cell(5,2).value,Cell(5,3).value,Cell(5,4).value,Cell(5,5).value,Cell(5,6).value,))
db.commit()
db.close()
...but attempts at multiple rows will fail. I suspect either issues while traversing rows in Excel. Here is what I have so far...
import MySQLdb
db = MySQLdb.connect(host="xxx.com", user="xxx", passwd="xxx", db="xxx")
c = db.cursor()
c.execute("select * from users")
usersss = c.fetchall()
updates = []
row = 2 # starting row
while True:
data = tuple(CellRange((row,1),(row,6)).value)
if data[0]:
if data not in usersss: # new record
updates.append(data)
row += 1
else: # end of table
break
c.executemany("""INSERT INTO users (id, username, password, userid, fname, lname) VALUES (%s, %s, %s, %s, %s, %s)""", updates)
db.commit()
db.close()
...as of now, I don't get any errors, but my new line is not added (id 3). This is what my table looks like in Excel...
The database holds the same structure, minus id 3. There has to be a simpler way to traverse the rows and pull the unique content for INSERT, but after 6 hours trying different things (and 2 new Python books) I am going to ask for help.
If I run either...
print '[%s]' % ', '.join(map(str, updates))
or
print updates
my result is
[]
So this is likely not passing any data to MySQL in the first place.
LATEST UPDATE AND WORKING SCRIPT
Not exactly what I want, but this has worked for me...
c = db.cursor()
row = 2
while Cell(row,1).value != None:
c.execute("""INSERT IGNORE INTO users (id, username, password, userid, fname, lname)
VALUES (%s, %s, %s, %s, %s, %s);""",
(CellRange((row,1),(row,6)).value))
row = row + 1
Here is your problem:
while True:
if data[0]:
...
else:
break
Your first id is 0, so in the first iteration of the loop data[0] will be falsely and your loop will exit, without ever adding any data. What you probably ment is:
while True:
if data[0] is not None:
...
else:
break
I ended up finding a solution that gets me an Insert on new and allows for UPDATE of those that are changed. Not exactly a Python selection based on a single query, but will do.
import MySQLdb
db = MySQLdb.connect("xxx","xxx","xxx","xxx")
c = db.cursor()
row = 2
while Cell(row,1).value is not None:
c.execute("INSERT INTO users (id, username, password, \
userid, fname, lname) \
VALUES (%s, %s, %s, %s, %s, %s) \
ON DUPLICATE KEY UPDATE \
id=VALUES(id), username=VALUES(username), password=VALUES(password), \
userid=VALUES(userid), fname=VALUES(fname), lname=VALUES(lname);",
(CellRange((row,1),(row,6)).value))
row = row + 1
db.commit()
db.close()
I'm having a small problem with a Python program (below) that I'm writing.
I want to insert two values from a MySQL table into another table from a Python program.
The two fields are priority and product and I have selected them from the shop table and I want to insert them into the products table.
Can anyone help? Thanks a lot. Marc.
import MySQLdb
def checkOut():
db = MySQLdb.connect(host='localhost', user = 'root', passwd = '$$', db = 'fillmyfridge')
cursor = db.cursor(MySQLdb.cursors.DictCursor)
user_input = raw_input('please enter the product barcode that you are taking out of the fridge: \n')
cursor.execute('update shops set instock=0, howmanytoorder = howmanytoorder + 1 where barcode = %s', (user_input))
db.commit()
cursor.execute('select product, priority from shop where barcode = %s', (user_input))
rows = cursor.fetchall()
cursor.execute('insert into products(product, barcode, priority) values (%s, %s)', (rows["product"], user_input, rows["priority"]))
db.commit()
print 'the following product has been removed from the fridge and needs to be ordered'
You don't mention what the problem is, but in the code you show this:
cursor.execute('insert into products(product, barcode, priority) values (%s, %s)', (rows["product"], user_input, rows["priority"]))
where your values clause only has two %s's in it, where it should have three:
cursor.execute('insert into products(product, barcode, priority) values (%s, %s, %s)', (rows["product"], user_input, rows["priority"]))
Well, the same thing again:
import MySQLdb
def checkOut():
db = MySQLdb.connect(host='localhost', user = 'root', passwd = '$$', db = 'fillmyfridge')
cursor = db.cursor(MySQLdb.cursors.DictCursor)
user_input = raw_input('please enter the product barcode that you are taking out of the fridge: \n')
cursor.execute('update shops set instock=0, howmanytoorder = howmanytoorder + 1 where barcode = %s', (user_input))
db.commit()
cursor.execute('select product, priority from shop where barcode = %s', (user_input))
rows = cursor.fetchall()
Do you need fetchall()?? Barcode's are unique I guess and one barcode is to one product I guess. So, fetchone() is enough....isn't it??
In any case if you do a fetchall() its a result set not a single result.
So rows["product"] is not valid.
It has to be
for row in rows:
cursor.execute('insert into products(product, barcode, priority) values (%s, %s, %s)', (row["product"], user_input, row["priority"]))
db.commit()
print 'the following product has been removed from the fridge and needs to be ordered'
or better
import MySQLdb
def checkOut():
db = MySQLdb.connect(host='localhost', user = 'root', passwd = '$$', db = 'fillmyfridge')
cursor = db.cursor(MySQLdb.cursors.DictCursor)
user_input = raw_input('please enter the product barcode that you are taking out of the fridge: \n')
cursor.execute('update shops set instock=0, howmanytoorder = howmanytoorder + 1 where barcode = %s', (user_input))
cursor.execute('insert into products(product, barcode, priority) select product, barcode, priority from shop where barcode = %s', (user_input))
db.commit()
Edit: Also, you use db.commit() almost like print - anywhere, you need to read and understand the atomicity principle for databases