I've been given a messy Excel file that I am trying to transfer into tidied SQL tables. I am building a Python program to do the transfer. There is a list of names, some of which are repeated. I've already gotten the column with all the names into a list of tuples like:
[(John Christopher, ), (Elizabeth Smith, ), (etc, )]
I've built an SQL table called Players and have an empty column named "id". I'm trying to iterate through this list and assign a unique id to each player in the Table and then also delete the duplicate names in my table.
However I keep getting this error:
cursor.execute("UPDATE Players SET id = "+str(id)+" WHERE name = "+str(item[0]))
sqlite3.OperationalError: near "Christopher": syntax error
What is my issue?
Here is the code:
import sqlite3
player_list_start = cursor.execute("SELECT name FROM Players")
saved_list = player_list_start.fetchall()
# number id should start on
id = 1
# list of players to keep track if they are already in the table
names = []
for item in saved_list:
if item[0] not in names:
cursor.execute("UPDATE Players SET id = "+str(id)+" WHERE name = "+str(item[0]))
connection.commit()
names.append(item[0])
id += 1
else:
cursor.execute("DELETE FROM Players WHERE name = "+str(item[0])+" AND id = NULL")
connection.commit()
It definitely says sqlite3.OperationalError: near "Christopher": syntax error .
The following line will generate syntactically wrong SQL statement because it does not quote strings (especially including spaces).
cursor.execute("DELETE FROM Players WHERE name = "+str(item[0])+" AND id = NULL")
Use
cursor.execute("DELETE FROM Players WHERE name = '"+str(item[0])+"' AND id = NULL")
or
cursor.execute("DELETE FROM Players WHERE name = ? AND id = NULL", (str(item[0]),))
Related
I am trying to update a row in an sql table based on results of a select query using python. How to add same so that if results found in select query we should be able to run update query and print as list updated, if not exit saying no result found to update table
cursor = conn.cursor()
cursor.execute(
"select * from student where email = 'xyz.com'"
)
student = cursor.fetchall()
print(student)
for row in student:
cursor.execute(" Update student set value = 0 where email = 'xyz.com'")
`
You don't need to do a separate SELECT, you can just use an OUTPUT clause to have your UPDATE statement return the value(s) from the row(s) that are updated. For example, with pyodbc:
sql = """\
UPDATE student SET value = 0
OUTPUT INSERTED.student_number
WHERE email = 'xyz.com' AND (value <> 0 OR value IS NULL)
"""
student_numbers = crsr.execute(sql).fetchall()
print(student_numbers) # [(1001, ), (1003, )]
I've written this code to create a list of user inputs which represent products in an SQLite DB table.
The list is referred to as basket, and now for each item in basket I want to create a record in another table which contains the orderID from the record I just created and the product ID which will come from the basket.
My current solution is very messy and looks like this:
shopping = True
while shopping:
itemToAdd = input("Please enter the ID of the item to add to the basket: ")
basket.append(itemToAdd)
print(basket)
continueShop = input("Continue shopping?(y/n): ")
if continueShop == "n":
conn.execute("INSERT INTO Orders (UserID) VALUES (?)", (results[0][0],))
conn.commit()
counter = 0
for items in basket:
createOrderItems = "INSERT INTO OrderItems (OrderID, ProductID) VALUES (?,?)"
currentOrder = "SELECT * FROM Orders WHERE UserID = (?)"
conn.execute(currentOrder, (results[0][0],))
conn.execute(createOrderItems, (currentOrder, basket(counter)))
counter = +1
Currently this gives the error
line 108, in <module>
conn.execute(createOrderItems, (currentOrder, basket(counter)))
TypeError: 'list' object is not callable
googling the problem was giving me the exact opposite of what I was trying to find so sorry if this is a poor question, I'm just really lost with this now having tried all I could think of.
UPDATE:
shopping = True
while shopping:
itemToAdd = input("Please enter the ID of the item to add to the basket: ")
basket.append(itemToAdd)
print(basket)
continueShop = input("Continue shopping?(y/n): ")
if continueShop == "n":
conn.execute("INSERT INTO Orders (UserID) VALUES (?)", (results[0][0],))
conn.commit()
counter = 0
for items in basket:
createOrderItems = "INSERT INTO OrderItems (OrderID, ProductID) VALUES (?,?)"
currentOrder = ("SELECT * FROM Orders WHERE UserID = (?)", (results[0][0]))
conn.execute(createOrderItems, (currentOrder, basket[counter]))
counter = +1
conn.commit()
Updated the code to include basket[counter] instead of basket(counter) and that got rid of the error, however the raw sql statement itself was being added to the table instead of the ID the statement is meant to locate so I have attempted to fix that aswell by changing currentOrder, however it now gives this error:
line 107, in <module>
conn.execute(createOrderItems, (currentOrder, basket[counter]))
sqlite3.InterfaceError: Error binding parameter 0 - probably unsupported type.
Change this:
basket(counter)
To this:
basket[counter]
Also, currentOrder in same line must be an id, you currently pass the entire sql statement. Try to pass the
currentOrder[0][x]
where x is the column position (1st, 2nd, 5fth, etc) of the column that represents the OrderId in your Orders table. So, this line should become:
conn.execute(createOrderItems, (currentOrder[0][x], basket[counter]))
Hello I'm having a hard time trying to make this function in which I have to:
"""Returns a list of the players and their win records, sorted by wins.
The first entry in the list should be the player in first place, or a player
tied for first place if there is currently a tie.
Returns:
A list of tuples, each of which contains (id, name, wins, matches):
id: the player's unique id (assigned by the database)
name: the player's full name (as registered)
wins: the number of matches the player has won
matches: the number of matches the player has played
"""
currently I have this function to try solve that:
def playerStandings():
conn = connect()
c = conn.cursor()
c.execute("SELECT id, name \
FROM players LEFT JOIN matches \
ON players.id = matches.id_winner \
ORDER BY players.id")
result = c.fetchall()
conn.close()
return result
and when I run the code I get this error msg:
Traceback (most recent call last): File "tournament_test.py", line
152, in
testStandingsBeforeMatches() File "tournament_test.py", line 61, in testStandingsBeforeMatches
raise ValueError("Each playerStandings row should have four columns.") ValueError: Each playerStandings row should have four
columns.
line 152 in tournament_test.py is:
testStandingsBeforeMatches()
and line 61 is:
if len(standings[0]) != 4:
raise ValueError("Each playerStandings row should have four columns.")
[(id1, name1, wins1, matches1), (id2, name2, wins2, matches2)] = standings
and finally variable "standings" is a call to my function playerStandings() in line 54
standings = playerStandings()
this is my sql script to create the database and the tables:
CREATE DATABASE tournament;
\c tournament;
CREATE TABLE players (id SERIAL, name TEXT, PRIMARY KEY (id));
CREATE TABLE matches (
id_match SERIAL,
id_winner SERIAL REFERENCES players(id),
id_looser SERIAL REFERENCES players(id),
PRIMARY KEY (id_match)
);
what can I do to solve this? I'm really new with python so I don't understand it very well
I don't use postgresql, the code may not use in your routine directly, so you need modify on this basis to let it work. I just give you some hints to let you know how to fix the problem.
def playerStandings():
conn = connect()
c = conn.cursor()
c.execute("SELECT id, name \
FROM players LEFT JOIN matches \
ON players.id = matches.id_winner \
ORDER BY players.id")
result = c.fetchall()#get all id and name, I don't know the type of result, assume its a list of dicts.
for row in result:
#sql to get wins
c.execute("SELECT COUNT(*) AS wins FROM WHERE id_winner = row['id']");
win_data = c.fetch()
row['wins'] = win_data['wins']
#sql to get matches
c.execute("SELECT COUNT(*) AS matches FROM WHERE id_winner = row['id']" OR id_looser = row['id'])
match_data = c.fetch()
row['matches'] = match_data['matches']
conn.close()
return result
I am able to get my Python code to run print the desired results, but my problem is with the SQLite table. I was asked to apply this SQL command to the tables:
SELECT hex(User.name || Course.title || Member.role ) AS X
FROM User JOIN Member JOIN Course
ON User.id = Member.user_id AND Member.course_id = Course.id
ORDER BY X
I was able to execute the command in SQLite, but according to the instructions for this project, X is supposed to start with 416 in row one of the results column produced. However, the X I got for row 1 in the results was:
43616C6962736933313030
Here is what I wrote in Python so far:
import sqlite3
import json
#Working with Java and Sqlite
conn = sqlite3.connect('rosterdb.sqlite')
cur = conn.cursor()
cur.executescript('''
DROP TABLE IF EXISTS User;
DROP TABLE IF EXISTS Member;
DROP TABLE IF EXISTS Course;
CREATE TABLE User(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
name TEXT UNIQUE
);
CREATE TABLE Member(
user_id INTEGER UNIQUE,
course_id INTEGER UNIQUE,
role INTEGER,
PRIMARY KEY (user_id, course_id)
);
CREATE TABLE Course(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
title TEXT UNIQUE
);
''')
#primary key for junction table is composite of both user_id and course_id
fname = raw_input("Enter file name:")
if (len(fname) < 1): fname = 'roster_data.json'
#prompts for file name
str_data = open(fname).read()
json_data = json.loads(str_data)
#opens the file and reads it all
#loads the json data and now is a python list
for entry in json_data:
title = entry[1];
name = entry [0];
role = entry[2];
#["Charley, "sill0", 1] represents the name, course title, and role
print name, title, role
cur.execute('''INSERT or IGNORE INTO User (name)
VALUES (?)''', (name, ))
cur.execute('SELECT id FROM User WHERE name = ?',(name, ))
user_id = cur.fetchone()[0]
cur.execute('''INSERT or IGNORE INTO Course (title)
VALUES (?)''', (title, ))
cur.execute('SELECT id FROM Course WHERE title = ?', (title, ))
course_id = cur.fetchone()[0]
cur.execute('''INSERT or REPLACE INTO Member (user_id, course_id, role)
VALUES (?,?,?)''', (user_id, course_id, role))
#INSERT, SELECT AND FETCHONE STATEMENTS
conn.commit()
Here is the JSON data that I was working with. It is about course registration for students: roster_data.json Here is the link to it:
https://pr4e.dr-chuck.com/tsugi/mod/sql-intro/roster_data.php?PHPSESSID=9addd537cfe55c03585d2bfaa757f6b0
I am not sure if I implemented the "role" key correctly. Thank you for your inputs!
The problem is that you made Member.course_id unique. Thus you can have no more members than courses. Using REPLACE in INSERT or REPLACE into Member hides this error.
Just drop UNIQUE constraint on Member.course and you will get expected result.
I am writing a program in which two variables are selected from QCombobBoxes which are populated with results from a MySQL query. I then take these variable and insert them into a MySQLdb statement that inserts the variables into a different MySQL table. The first variable works fine, however on the second I get this error,
TypeError: 'NoneType' object has no attribute '__getitem__'
The code is identical for both variables, with the exception of different names
name = str(self.item_name.currentText())
cur.execute("SELECT item_id FROM Items WHERE name = '%s';"), name
db.commit()
results = cur.fetchone()
item_name = results[0]
personnel_name = str(self.purchaser_name.currentText())
cur.execute("SELECT personnel_id FROM Personnel WHERE name = '%s';"), personnel_name
db.commit()
results = cur.fetchone()
purchaser_id = results[0]
After playing with it, it looks like cur.execute("SELECT item_id FROM Items WHERE name = '%s';"), name is inserting an extra pair of quotation marks around the value that replaces %s Does anyone know why it's doing this and how to stop it? I coded both variables exactly the same, and it seems that name is getting an extra pair of quotes from MySQL
This is code that populates QComboBox:
#Get list of items currently in the database
cur = db.cursor()
cur.execute("SELECT name FROM Items")
db.commit()
results = cur.fetchall()
for name in results:
self.item_name.addItem(name[0])
#Get list of purchaser names
cur.execute("SELECT name FROM Personnel")
db.commit()
results = cur.fetchall()
for name in results:
self.purchaser_name.addItem(name[0])
If I manually insert a variable, it works fine. ex: cur.execute("SELECT item_id FROM Items WHERE name = 'Wire';") Only when I use string formatting with %s does the error occurr.
c.execute("SELECT * FROM sometable WHERE some_condition=?","My Condition")
you should always use the ? placeholders for this kind of thing
[edit]
try 1. cur.execute("SELECT item_id FROM Items WHERE name = '%s';"%(name,))
or 2. cur.execute("SELECT item_id FROM Items WHERE name = %s;", (name,))
from my brief reading, I think that mysql driver will automatically quote %s arguments
my conclusion is that cur.execute("SELECT item_id FROM Items WHERE name = %s;", (name,)) is the most correct way to do this(to avoid injection etc).