self.cursor.execute('INSERT INTO User where User_name=(?) (user_name,user_password,user_wins,user_loses) VALUES(?,?,?,?)',(a,a,b,c,d))
self.connect.commit()
Logically i would have thought this would work but im not sure why it hasnt?
The first '?' in the sql statement is the same as 'a'.
I get this error:
sqlite3.OperationalError: near "where": syntax error
So im wondering if it is actually possible to write to an already written row in a SQL database?
INSERT means add a completely new row. If you want to alter an existing row, you need UPDATE.
For instance
UPDATE User
SET user_password=?,
user_wins=?,
user_loses=?
WHERE user_name=?
passing the user name as the last variable.
So something like:
self.cursor.execute(
'UPDATE User SET user_password=?, user_wins=?, user_loses=? WHERE user_name=?',
(b,c,d,a)
)
Related
I'm trying to write a query for sqlite3 to check if a discordID exists in my database and increment the associated count variable if it exists and if not it should add a new row with that discordID and its associated count increased by one.
crs.execute("INSERT OR IGNORE INTO {0} (discordID,count) VALUES ({1},1) UPDATE {0} SET count = count + 1 WHERE discordID = {1};".format(tableName,user))
I tried this query (where user is an input discordID) however I keep getting the error:
sqlite3.OperationalError: near "UPDATE": syntax error
and I would like to know why this happening and how it can be fixed or if there's a better way to be doing this.
What you are looking for is an UPSERT. This allows you to specify an ON CONFLICT clause that will be executed if the INSERT would violate a constraint.
Applied to your query, it should look something like this:
crs.execute("INSERT INTO {0} (discordID,count) VALUES ({1},1) ON CONFLICT(discordID) DO UPDATE SET count = count + 1;".format(tableName,user))
On a side note: you should avoid inserting user-generated content directly into your database and/or query strings. If you need to store user-generated inputs, look into using prepared statements, otherwise you'll be vulnerable to SQL Injection
I don't know how to make this SQL Injection work in SQLite. I'm using a function in Python that connects to a database and inserts a string.
I have "database.db" that has two tables: "feedback" and "users".
The feedback table has 1 column: message.
The users table has 2 columns: username and password.
def send_feedback(feedback):
conn = sqlite3.connect("database.db")
curs = conn.cursor()
curs.execute("INSERT INTO feedback VALUES ('%s')" % (feedback))
print(curs.fetchall())
conn.close()
I know that the execute function allows me to make a single query to the database, so I can't use ";" to
make multiple queries.
What I have tried, is to make the string look like this:
a') SELECT password FROM users --
feedback = "INSERT INTO feedback VALUES ('a') SELECT password FROM users --')"
But this gives me the following error:
sqlite3.OperationalError: near "SELECT": syntax error
So I've tried to use the UNION command:
a') UNION SELECT password FROM users --
feedback = "INSERT INTO feedback VALUES ('a') UNION SELECT password FROM users --')"
This one works but the fetchall function returns an empty list.
Most SQL injections result in nothing useful to the perpetrator, just a syntax error.
For example, pass the string "I'm not satisfied" to this feedback function and the extra ' character would cause the quotes to be imbalanced, and this would result in an error, causing the INSERT to fail.
sqlite3.OperationalError: near "m": syntax error
That's technically SQL injection. The content interpolated into the query has affected the syntax of the SQL statement. That's all. It doesn't necessarily result in a successful "Mission: Impossible" kind of infiltration.
I can't think of a way to exploit the INSERT statement you show to make it do something clever, besides causing an error.
You can't change an INSERT into a SELECT that produces a result set. Even if you try to inject a semicolon followed by a second SQL query, you just get sqlite3.Warning: You can only execute one statement at a time
Your first try above resulted in a syntax error because you had both a VALUES clause and a SELECT as a source for the data to insert. You can use either one but not both in SQL syntax. See https://www.sqlite.org/lang_insert.html
You probably already know how to make the code safe, so unsafe content cannot even cause a syntax error. But I'll include it for other readers:
curs.execute("INSERT INTO feedback VALUES (?)", (feedback,))
You can do it, for example to get table name
a' || (SELECT tbl_name FROM sqlite_master WHERE type='table' and tbl_name NOT like 'sqlite_%'))-- -
my question is, as the title says, how I can create a variable column in SQL lite used in Pyhton.
Here's my code, to show you what exactly I mean:
#Table with variables
def dynamic_data_entry(list_name, num, column):
element_name = list_name[num]
cur.execute("INSERT INTO myliltable (column) VALUES (?)", element_name)
con.commit()
I want to insert the column name, when I call the function, so I can use the function for more than one column, but I keep getting an error, that the column 'column' doesn't exist.
Is there another way to do this, so I can change set the column name when I call the function, or just change the SQL part.
If there is a thread about this already, I would appreciate it, if you could link it, so I can read it myself (I couldn't find anything similar to this topic yet, which worked).
Thanks in advance, I appreciate your help
You need to use the string's format() method to insert the column name into the SQL string:
cur.execute("INSERT INTO myliltable ({}) VALUES (?)".format(column),
element_name)
You can find more information in the Python docs.
So I'm working in a Python 3.5.2 venv with SQLAlchemy and MySQL. I'm trying to update the status of an order (row) in a table. This requires simply changing the value of one column in a row. The following shows the function I'm working with:
def update_order_status(self, order):
newstatus = self.orderwindow.status.currentIndex()
orderid = order.orderid
stmt = update(Order)\
.where(Order.orderid == orderid).values(status=newstatus)
session.execute(stmt)
session.commit()
newstatus is an integer value taken from the current choice set
in a dropdown menu presented to the user. Upon the session.commit()the following errors are
.....
File "C:\Python35\Python35-32\lib\site-packages\MySQLdb\connections.py", line 292, in query
_mysql.connection.query(self, query)
sqlalchemy.exc.OperationalError: (_mysql_exceptions.OperationalError) (1366, "Incorrect integer value: 'Patient' for column 'bill' at row 1") [SQL: 'UPDATE `order` SET bill=%s, ship=%s, status=%s, flavor=%s WHERE `order`.orderid = %s'] [parameters: ('Patient', 'Pickup', 'Received', 7, 100000)]
......
Process finished with exit code 1
The parameters executed are not at all what is shown in the prepared statement. It should only be updating the row with the orderid matching the one provided as a parameter to the function and the status from the dropdown.
I've updated all packages and tried other methods of updating including setattr(order, "status", newstatus)
I'm unsure of what to do to diagnose this error.
EDIT: I forgot to mention earlier that this function actually works flawlessly in a python console after copy-pasting my database declarations script first.
Seems I've answered my own question. I remembered that I was querying the order table earlier in my program and then changing its attributes from integers to user-friendly strings. When the update was being called, it was using the now changed order object which had values contradicting the table column types.
I didn't know that the update function attempts to update the entire object rather than just the columns provided in the .values() field. As a result I've had to revamp my handling of orders and instead I'm putting them into dictionaries and referencing the table again to update the original order.
I'm trying to figure out if it's possible to replace record values in a Microsoft Access (either .accdb or .mdb) database using pyodbc. I've poured over the documentation and noted where it says that "Row Values Can Be Replaced" but I have not been able to make it work.
More specifically, I'm attempting to replace a row value from a python variable. I've tried:
setting the connection autocommit to "True"
made sure that it's not a data type issue
Here is a snippet of the code where I'm executing a SQL query, using fetchone() to grab just one record (I know with this script the query is only returning one record), then I am grabbing the existing value for a field (the field position integer is stored in the z variable), and then am getting the new value I want to write to the field by accessing it from an existing python dictionary created in the script.
pSQL = "SELECT * FROM %s WHERE %s = '%s'" % (reviewTBL, newID, basinID)
cursor.execute(pSQL)
record = cursor.fetchone()
if record:
oldVal = record[z]
val = codeCrosswalk[oldVal]
record[z] = val
I've tried everything I can think bit cannot get it to work. Am I just misunderstanding the help documentation?
The script runs successfully but the newly assigned value never seems to commit. I even tried putting "print str(record[z])this after the record[z] = val line to see if the field in the table has the new value and the new value would print like it worked...but then if I check in the table after the script has finished the old values are still in the table field.
Much appreciate any insight into this...I was hoping this would work like how using VBA in MS Access databases you can use an ADO Recordset to loop through records in a table and assign values to a field from a variable.
thanks,
Tom
The "Row values can be replaced" from the pyodbc documentation refers to the fact that you can modify the values on the returned row objects, for example to perform some cleanup or conversion before you start using them. It does not mean that these changes will automatically be persisted in the database. You will have to use sql UPDATE statements for that.