How would I update an entry that is already in a database using sqlite3?
I've tried:
db_curs.execute("INSERT INTO `database` (cID) VALUES ('Updated')")
But this, of course, creates a new entry. I can obtain the (line(?)) number (of the entry) and what is the command to update the database rather than create a new entry?
EDIT:
Put a bit better, when I convert the SQL entry to a python list I get the following,
(1, u'GGS-04', u'John', u'Smith', 9, u'0')
I need to be able to add a digit to the last item. Here is what I have.
info = (1, u'GGS-04', u'John', u'Smith', 9, u'0')
for result in info:
ln = str(result[0])
ggs = str(result[1])
first_name = str(result[2])
last_name = str(result[3])
dob = str(result[4])
spend = str(result[5])
while True:
res = raw_input("Enter points to add: ")
try:
int(res)
break
except:
print "Please enter a number..."
pass
spend = str(int(spend) + int(res))
db_curs.execute("UPDATE `" + db_name + "` (cID, first_name, last_name, date_of_birth, spend) VALUES ('" + srce + "', '" + first_name + "', '" + last_name + "', '" + dob + "' WHERE '" + spend + "')")
db_connection.commit()
Could someone please explain the correct syntax for this command? It would be awesome if I could just update the "Spend" column than having to update them all from prefixed variables.
Thank you :)
This shall work:
db_curs.execute("UPDATE database SET spend =`" + spend + "` WHERE cID="+ cID)
See also SQL Update Syntax
Btw, "database" isn't a useful name for a database's table. What about "users" or "spendtime" or sth more descriptive?
Related
Here is my code, it is to insert data into a database, , if i use numbers it works, but not with text, how do i solve it? I think i need to put «data» between two quotation marks ", how do i do that?
Thanks
def aggiungi():
print('funzione \'aggiungi\'')
conn = db.connect(NOMEDB)
print
"Database aperto con successo";
cognome, nome, indirizzo, mail, tel_fisso, tel_cell = input(
"Inserire cognome, nome, indirizzo, mail, tel_fisso, tel_cell (separati da virgola): ").split(",")
dati = cognome + "," + nome + "," + indirizzo + "," + mail + "," + tel_fisso + "," + tel_cell
conn.execute("INSERT INTO contatti (cognome, nome, "
f"indirizzo, mail, tel_fisso, tel_cell) VALUES ({dati})");
conn.commit()
print ("Records created successfully)")
conn.close()
return
You are missing a + to concatenate strings "INSERT INTO contatti (cognome, nome, " and f"indirizzo, mail, tel_fisso, tel_cell) VALUES ({dati})".
However, I should point out that this approach is highly dangerous for the security of your database, as it could be attacked with SQL injection. Basically, you are inserting a generic string into your query, without checking its content.
For instance, a malicious user could add this string for tel_cell:
3290000000);SELECT * FROM contatti --
This would cause your database to execute whatever query the malicious user likes.
Solution is to prepare your query. Further readings on this:
https://docs.python.org/3/library/sqlite3.html (see last example before "Module functions and constants")
https://www.websec.ca/kb/sql_injection
I have two web services called getCourseCodeWS and checkStudentOnCourseWS both with 1 corresponding DB. The first WS returns a courseCode from a DB. This courseCode should work as a parameter in my checkStudentOnCourseWS which should use the courseCode + another parameter called personalIdentityNumber, which I get from checkStudentOnCourseWS's DB. This should return a true/false depending on if the arguments match the database, in other words, if the student appears in the course.
My question is how do I request the actual respons I get from my getCourseCodeWS to work as an argument for checkStudentOnCourseWS?
#app.route('/courses/<course>/<period>', methods= ["GET"])
def checkCourseCodeWS(course, period):
myCursor2 = mydb.cursor()
query2 = ("SELECT courseCode FROM paraplyet.courseInfo WHERE courseName = " + "'" + course + "' AND duration = " + "'" + period + "'")
myCursor2.execute(query2)
myresult2 = myCursor2.fetchall()
return jsonify(myresult2)
I have the following values In Python values:
_sfwBIPMKEeCTfuMZpaDEBQ Atomic Warehouse Model None
These values are sent through a function and is being put into a db3 table like this:
INSERT INTO [PackageRoster] (PkgID, Package, PkgParentID) VALUES ('_sfwBIPMKEeCTfuMZpaDEBQ', 'Atomic Warehouse Model', 'None');
I do not want the string 'None' put into the table. I would like NULL.
How do I tell Python to inject NULL instead of None?
Here's the function that works the statement (includes debug feature):
def StorePackage(PkgID, Package, PkgParentID):
dbutils.ResetTable()
conn = sqlite3.connect(dbutils.db)
try:
conn.execute("INSERT INTO " + dbutils.table + " (PkgID, Package, PkgParentID) VALUES ('" + PkgID + "', '" + Package + "', '" + PkgParentID + "');")
except:
print("INSERT INTO " + dbutils.table + " (PkgID, Package, PkgParentID) VALUES ('" + PkgID + "', '" + Package + "', '" + str(PkgParentID) + "');")
conn.commit()
Thanks
I initially commented a recommendation to use parameter substitution, assuming it wasn't actually related. On further inspection, though, I think it's exactly what you're looking for.
Your code currently inserts all strings because you're explicitly converting everything to a string in Python. Parameter substitution enables Python to handle how to get its values into the database, and also protects you from SQL injection attacks.
conn.execute("INSERT INTO " + dbutils.table + " (PkgID, Package, PkgParentID) VALUES (?,?,?)", (PkgID, Package, PkgParentID))
A Python None object will be inserted as an SQLite NULL using this method. You can read more about parameter substitution in the docs, as well as how Python values are converted to SQLite values and vice versa.
You are converting all of your values to strings, because you add quotes arround them. I.e, because you do '" + str(PkgParentID) + "' it will end up as 'None' instead of None.
You should for example convert your values to a string before the query, and replace them with NULL when they are None:
def StorePackage(PkgID, Package, PkgParentID):
PkgParentID = "'{}'".format(PkgParentID) if PkgParentID is not None else "NULL"
# Same for other parameters if desired
dbutils.ResetTable()
conn = sqlite3.connect(dbutils.db)
query = "INSERT INTO " + dbutils.table + " (PkgID, Package, PkgParentID) VALUES ('" + PkgID + "', '" + Package + "', " + PkgParentID + ");"
try:
conn.execute(query)
except:
print(query)
conn.commit()
Also you should use parameter substitution, although thats not what is causing your issue in the first place
I am new to programming and working on a homework assignment. I am trying to search a database by comparing a user's search term with any matching values from a selected column. If a user searches "Smith" and clicks on the "Smith" radio button in my GUI, all the records containing "Smith" as its author should appear. I am able to print all the records in the database, but not the records that relate to my search.
db = None
colNum = None
def search_db(self):
global db
global colNum
self.searchTerm = self.searchvalue.get()
dbname = 'books.db'
if os.path.exists(dbname):
db = sqlite3.connect(dbname)
cursor = db.cursor()
sql = 'SELECT * FROM BOOKS'
cursor.execute(sql)
rows = cursor.fetchall()
for record in rows:
sql_search = 'SELECT * FROM BOOKS WHERE' + ' ' + record[colNum] + ' ' + 'LIKE "%' + ' ' + self.searchTerm + '%"'
cursor.execute(sql_search)
searched_rows = cursor.fetchall()
print(searched_rows)
The error I'm receiving is "sqlite3.OperationalError: no such column:"
There isn't enough information in your question to be sure, but this certainly is fishy:
sql_search = 'SELECT * FROM BOOKS WHERE' + ' ' + record[colNum] + ' ' + 'LIKE "%' + ' ' + self.searchTerm + '%"'
That record[colNum] is the value in a row for your column, not the name of the column. For example, if the column you wanted is Title, you're going to treat every title of every book as if it were a column name.
So, you end up running queries like this:
SELECT * FROM BOOKS WHERE The Meaning of Life: The Script like %Spam%
Even if that were valid SQL (quoted properly), The Meaning of Life: The Script is probably not a column in the BOOKS table.
Meanwhile, SELECT * returns the columns in an arbitrary order, so using colNum isn't really guaranteed to do anything useful. But, if you really want to do what you're trying to do, I think it's this:
sql = 'SELECT * FROM BOOKS'
cursor.execute(sql)
colName = cursor.description[colNum][0]
sql_search = 'SELECT * FROM BOOKS WHERE ' + colName + ' LIKE "%' + ' ' + self.searchTerm + '%"'
However, you really shouldn't be wanting to do that…
You need to get the column name from the fields of the table, or from somewhere else. Your query uses record[colNum] but record contains rows of data. Instead, to get the field names, use something like this:
fields = []
for field in cursor.description:
fields.append(field[0])
When you use rows = cursor.fetchall(), you are only getting data (and not the column headers).
It looks to me like you are just not forming the SQL correctly. Remember that whatever you put after the LIKE clause needs to be quoted. Your SQL needs to look like
SELECT * FROM BOOKS WHERE Title like '%Spam%'
So you need another set of single quotes in there so that's why I would use double quotes to surround your Python string:
sql_search = "SELECT * FROM BOOKS WHERE " + record[colNum] + " LIKE '%" + self.searchTerm + "%'"
I have a web form taking user data and putting it into a mysql database. I need to trim leading and trailing blanks/spaces. I currently am utilizing the strip() method, but it only trims them for the fields, NOT for the mysql database.
My code is:
first_name = first_name.strip()
last_name = last_name.strip()
so on and so forth. It strips it perfectly fine for the webpage, but not when it is entered into the SQL database. The spaces still exist. How do I remove them?
EDIT:
db = MySQLdb.connect("localhost","user","pass","db_name")
cursor = db.cursor()
cursor.execute("Select * FROM registrants")
cursor.execute("INSERT INTO registrants VALUES( " + "'" + first_name + "'" + ", " + "'" + last_name + "'" + ");")
db.commit()
db.close()
It could be a scope issue.
If the stripping occurs in a different scope (ex: first_name is a global variable and the strip() occurs in a function) then you will not benefit from it in another scope (if the insert is happening in another function for example).
Have you tried this for a test:
cursor.execute("INSERT INTO registrants VALUES( " + "'" + first_name.strip() + "'" + ", " + "'" + last_name.strip() + "'" + ");")
btw, how do you know there's a space in the db? There could be an issue with the way the data is retrieved or displayed..
I think you should be passing the values into the INSERT differently
cursor.execute("INSERT INTO registrants (fname, lname) VALUES (%s, %s)", (first_name, last_name)
I'm not sure if that's where you're getting the whitespace, but it opens you up to sql injection so it's bad form to put the variables straight into the query.