I apologize for posting so much code, I couldn't get the behavior to repeat on an abstracted simplified program so I had to post the actual code.
The goal is for the contents of the cart table to be placed in the orders and odetails table.
What is actually happening is that if there is one entry in the cart there will be more than ten entries in the orders tables. The way I see the for loops that execute after insertSql is that it will run through the entire loop once and exit on the break. That is, it executes insertSql then it retrieves the order number ono then it sets the class attribute orderNumber to the retrieved order number ono and sets the cart to empty. What am I missing?
I am using Python 2.7 and the modules cmd and cx_Oracle.
def oneClick(self,userLoggedIn):
#this checks if there is a credit card available, if there isn't it denies one click check out
sql = """
SELECT creditcardnumber, creditcardtype
FROM bs_members
WHERE userid = :userid
"""
ds.execute(sql,userid=userLoggedIn)
for row in ds:
if row == (None,None):
print """
One click check out is not available if you do not have a credit card on file.
"""
else:
break
#this checks to see if the user has anything in the cart
cartSql = """
SELECT DISTINCT userid FROM bs_cart WHERE userid = :userid
"""
ds.execute(cartSql,userid=userLoggedIn)
#this places the contents of the cart into the order tables
insertSql = """
BEGIN
INSERT INTO bs_orders (userid, ono, timePurchased)
VALUES (:userid, orderNum_seq.NEXTVAL,(SELECT current_timestamp FROM dual));
COMMIT;
UPDATE bs_orders
SET shipaddress = (SELECT address FROM bs_members WHERE userid = :userid)
, shipcity = (SELECT city FROM bs_members WHERE userid = :userid)
, shipstate = (SELECT state FROM bs_members WHERE userid = :userid)
, shipzip = (SELECT zip FROM bs_members WHERE userid = :userid)
WHERE userid = :userid
AND timePurchased IN
(
SELECT MAX(timePurchased)
FROM bs_orders
WHERE userid = :userid
GROUP BY userid
);
INSERT INTO bs_odetails (ono, isbn, qty, price)
SELECT orderNum_seq.CURRVAL, bs_cart.isbn, bs_cart.qty, bs_books.price
FROM bs_orders, bs_cart, bs_books
WHERE bs_orders.userid = :userid
AND bs_cart.userid = :userid
AND bs_books.isbn = bs_cart.isbn;
DELETE FROM bs_cart
WHERE userid = :userid;
END;
"""
#if the cart has contents this for loop is executed
for row in ds:
ds.execute(insertSql,userid=userLoggedIn)
sql = """
SELECT ono
FROM bs_orders
WHERE userid = :userid
AND timePurchased IN
(
SELECT MAX(timePurchased)
FROM bs_orders
WHERE userid = :userid
GROUP BY userid
)
"""
ds.execute(sql,userid=userLoggedIn)
for row in ds:
self.orderNumber = ''.join(str(i) for i in row)
self.cartIsEmpty = False
break
#if the cart does not have any contents the user is told to try again
else:
print """
You have nothing in your cart!
"""
self.cartIsEmpty = True
Related
I am trying to verify user by ensuring only registered users with a department can have access to the department template in the application. I want a situation whereby once a user enters his login details, his department would be checked by the system and through his login detail, the template for his department would be open. So it is the work of the application to identify the department he is through his login details and open the right template for him.
I want the system to loop through the other departments if he's not found in the first department, to see if he is registered in one of the others. Here's my code:
def verifyUser(self):
self.db_connection()
try:
username = self.user.text()
password = self.pwtx.text()
result = self.conn.execute(
"""SELECT *
FROM newUser_general
WHERE userID = ? AND dept = 'Comp Dept' """,
(username, password)
) # include dept
print("SQL Statement executed")
if (len(result.fetchall()) > 0):
print("user found")
self.compDept()
else:
print("user not found")
except Exception as err:
print(err)
I've finally gotten it right.
I used an if and else conditional statement.
First I instantiated the departments like dept1 = "Comp sci", dept2 = "Statistics"
Then I did
```if dept1:
result = self.cursor.connect(result = self.conn.execute(
"""SELECT *
FROM newUser_general
WHERE userID = ? AND dept = 'Comp Dept' """,
(username, password))
else if dept2:
result = self.cursor.connect(result = self.conn.execute(
"""SELECT *
FROM newUser_general
WHERE userID = ? AND dept = 'Statistics' """,
(username, password))```
Suppose you have a department table in your database, you can select all the department names or better their unique identifier first and store them in an array. Then you loop through the array and execute a request every time.
Another solution is to store the department of each user in the user table. Then when in the login process you can select his dept id.
I am trying to pass data into a nested sqlite3 query in python and I get the following error
Incorrect number of bindings supplied. The current statement uses 2, and there are 1 supplied.
x = uid
sql_query1 = """SELECT title FROM movies WHERE addedBy != ? AND mid NOT IN (SELECT mid FROM ratings WHERE uid = ?);"""
data = (uid, x)
cursor.execute(sql_query1, [data])
movies = cursor.fetchall()
I'm guessing the problem might be that x = uid, I have also tried data = (uid, uid) and cursor.execute(sql_query1, [uid]).
Parameters can be explicitly numbered, and the same value used for all instances of a given number:
sql_query1 = """
SELECT title
FROM movies
WHERE addedBy != ?1 AND mid NOT IN (SELECT mid FROM ratings WHERE uid = ?1);"""
cursor.execute(sql_query1, (uid,))
You need to supply as many parameters as you have question marks.
cursor.execute("""
SELECT title
FROM movies
WHERE addedBy != ?
AND mid NOT IN (SELECT mid FROM ratings WHERE uid = ?);
""", [uid, uid])
movies = cursor.fetchall()
I want to able to check if a record exists in the DB with a specific 'ID' and create one if it does not have one( i.e, Doesnt exist) Like so...
I would also like to fetch "Num" For a specific record after it has been updated.
import sqlite3 as lite
db = lite.connect("test.db")
id_to_be_added = "123456789101112"
db.execute("CREATE TABLE USERS (ID TEXT, NUM INT)")
Query = "{ SOMETHING IN SQL }" # This returns either True or False
if Query:
db.execute("UPDATE USERS SET NUM = NUM + 1 WHERE ID = {};".format(id_to_be_added))
else:
db.execute("INSERT INTO USERS ({}, 0)".format(id_to_be_added))
num_to_be_printed = db.execute("SELECT NUM FROM USERS WHERE ID = {}".format(id_to_be_added))
print("{0} has {1}").format(id_to_be_added, num_to_be_printed)
Either create a primary key and use INSERT OR REPLACE query, or use a SELECT query.
I was able to solve it using cur.fetchall()
import sqlite3 as lite
db = lite.connect(r"test.db")
id_tba = r"123456789101112"
cur = db.cursor()
cur.execute("SELECT * FROM USERS WHERE ID = {}".format(id_tba))
if len(cur.fetchall()) > 0:
db.execute("UPDATE USERS SET NUM = NUM + 1 WHERE ID = {};".format(id_tba))
else:
db.execute("INSERT INTO USERS ({}, 0)".format(id_tba))
num_to_be_printed = db.execute("SELECT NUM FROM USERS WHERE ID = {}".format(id_tba))
print("{0} has {1}").format(id_tba, num_to_be_printed)
I am new to Python and am hoping someone can help me figure out how to perform an SQL query on each item in a tuple using Python.
I have a SQL Express server that contains a number of databases for a badge reader system. What I am trying to do is pull the user id's that have scanned into a particular reader, then use those id's to get the actual user names.
Currently, I am able run the query that pulls the user id's and run a query on the other table using just one id. What want to be able to do, and seem to be having an issue figuring out, is running that second query on every user id in the tuple that is created from the first query. Below is the code for the two functions I am currently using.
def get_id():
global cardholder
global cur
cur.execute("SELECT user_id FROM db.table WHERE badgereaderid = 'badgereader1'")
cardholder = []
rows = cur.fetchall()
for row in rows:
if row == None:
break
cardholder.append(row[0])
print(cardholder)
def get_name():
global cardholder
global user
global cur
cur.execute("SELECT FirstName, LastName FROM db.table WHERE user_id= '%s'" % cardholder)
while 1:
row = cur.fetchone()
if row == None:
break
user = row[0] + row[1]
Two possible options
Repeated queries in Python
for user_id in cardholder:
cur.execute("SELECT FirstName, LastName FROM db.table WHERE user_id= '%s'" % user_id)
But why not just pull all the data in the first query?
cur.execute("SELECT a.user_id, b.FirstName, b.LastName FROM db.table1 a left join bd.table2 b on a.user_id = b.user_id WHERE a.badgereaderid = 'badgereader1'")
or, use triple quotes to allow multi-line strings and make the SQL command easier to understand
cur.execute("""SELECT
a.user_id,
b.FirstName,
b.LastName
FROM db.table1 a
left join db.table2 b
on a.user_id = b.user_id
WHERE a.badgereaderid = 'badgereader1'""")
A good practice in Python is to define the data collections outside the function if you intend to use them later on in your code
Try this code:
cardholder_names = []
#pass the cardholder as a param to the function
def get_name(cardholder):
#cur is already defined as a global param, no need to do it twice
cur.execute("SELECT FirstName, LastName FROM db.table WHERE user_id='{0}'".format(cardholder))
return cur.fetchone()
#now use the for loop to iterate over all the cardholders
for holder in cardholders:
cardholder_name = get_name(holder)
cardholder_names.append( {"name" : cardholder_name[0], "surname" : cardholder_name[1]})
I have a form which 4 input fields, when clicking the submit button, I'm fetching results from the database based on those 4 inputs. I'm not forcing the user to enter any input, so I could get all blank inputs or part of them empty. The more inputs the user fills, the results from the database will be more precise.
My problem is how to build the where part of the query dynamically using only the place holders which are populated. here is my query. This way if one of the inputs are blank, the query will not fetch anything while my intention is the opposite: if the input is blank, do not take into account while querying the database.
cursor.execute('''
SELECT name, id, gender, age, address, phones, mails, gender, age, hair_color
FROM persons
WHERE
name = ? AND
id = ? AND
gender = ? AND
age = ?
''', (name_input, id_input, gender_input, age_input))
You could create the WHERE clause dynamically:
sql = "SELECT ... WHERE 1"
parameters = []
if name_input != "":
sql += " AND name = ?"
parameters += [name_input]
if id_input != "":
sql += " AND id = ?"
parameters += [id_input]
...
Alternatively, rewrite the WHERE clause so that empty values are ignored:
SELECT ... WHERE (name = ?1 OR ?1 = '') AND (id = ?2 OR ?2 = '') AND ...
(?n specifies the n-th parameter.)