i have a hopefully simple Problem with an SQL-command
Code:
c.execute("SELECT MAX(pic_num) FROM Pictures WHERE id = "+str(user_id))
pic_num is a column in the database and user_id is an Integer in the database
I thought everything would be right but i get this
Error:
sqlite3.OperationalError: near ")": syntax error
this Information doesn't help me at all
The correct way to use python's db-api is to use placeholders in your SQL query and pass query values along, ie:
c.execute("SELECT MAX(pic_num) FROM Pictures WHERE id=?", [user_id,])
Note that this might not necessarily solve your problem but since you didn't post the schema nor the user_id value we can't try & reproduce the issue.
You should python sqlite module's substitution instead like so:
c.execute("SELECT MAX(pic_num) FROM Pictures WHERE id = ?", (user_id, ))
Thank you all for the fast answers!
c.execute("SELECT MAX(pic_num) FROM Pictures WHERE id = ?", (str(user_id), ))
this finally worked :)
I already have written some libs which should handle SQL-injection (they test the Input for quotes but you're right im very new with SQL :D)
Related
I am working on a project that uses a HTML text input to retrieve data from a SQLite database.
The idea goes like this : the user types string representing a product number and I look into my database for that string.
I have tried to make my query safe for SQL injection as suggested in this tutorial because the data does not come from me.
cursor.execute("SELECT product_number FROM price_history WHERE product_number = %s';", (user_input, ))
However, when I try to execute my code, I get :
sqlite3.OperationalError: near "%": syntax error
There's an extra ' after %s.
Read the first paragraphs of the python docs on sqlite3 that show the correct way to use placeholders.
cursor.execute("SELECT product_number FROM price_history WHERE product_number = (?)", (user_input, )) should work.
I'm using python module sqlite3 as per the below code:
# Enter the randomised data into the dictionary:
for square in cube:
cur.execute("UPDATE cubes SET ? = ? WHERE id = ?", (square, cube[square], session["current_cube_id"]))
con.commit()
Which results in the following error:
cur.execute("UPDATE cubes SET ? = ? WHERE id = ?", (square, cube[square], session["current_cube_id"]))
sqlite3.OperationalError: near "?": syntax error
I don't seem to have a problem with INSERT or SELECT queries, so I assume there is a specific syntax required to UPDATE. From the documentation, tutorials and other examples I can find this seems to be correct - can anyone please assist with what might be the syntax error?
You can't define table, column names, or SQL keywords, using bind variables (the SET ? =) in UPDATE cubes SET ? = ? WHERE id = ?
I am not sure why you feel you need to have a dynamic column name, rather than UPDATE cubes SET mycol = ? WHERE id = ? but you need to specify your column name differently.
You'd have the exact same problem with insert or delete if your target column names, in an insert, or your where condition column names in a delete, were getting specified with ? placeholders. I assume you did not do this so you did not get the error.
Be very careful if you decide to build your query string dynamically as in
myquery = f"UPDATE cubes SET {my_user_supplied_column_name} = ? WHERE id = ?"
cur.execute(myquery, (cube[square], session["current_cube_id"]))
That opens you to a large class of extremely serious vulnerabilities, the SQL Injections because the user may enter anything they want in my_user_supplied_column_name. Best to be very careful as it also has a reputational risk: a savvy prospective employer might for example reject your application if they saw this type of construct, unguarded, in your code because it is an extremely grave, frequent and well-known risk.
I work with the Python mysql.connector for the first time and I am not able to create a working insert statement.
This is the table:
'CREATE TABLE IF NOT EXISTS products (id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(255));'
I am trying to insert a variable as title while the id should be auto incremented. I have tried multiple solutions but it simply won't work.
def insert_product(title: str):
insert_product_query = 'INSERT INTO products (title) VALUES (%s);'
cursor.execute(insert_product_query, (title,))
This runs without any error, but the insert is not working. It does nothing. I tried multiple versions of this, with '?' instead of '%s' and without a tuple but it won't work.
Another solution I tried is this:
def insert_product(title: str):
insert_product_query = f'INSERT INTO products (title) VALUES (\'{title}\')'
print(insert_product_query)
cursor.execute(insert_product_query)
I printed the insert statement and when I copy paste it directly into the database it works perfectly, so I don't have any idea why it is not working out of the python code as it is not producing any errors.
I found many similar problems but none of the solution worked for me.
I hope someone can help me as I might overlook something obvious.
Thanks in advance!
Python's connector disables autocommit by default (as a reasonable library would do!). You need to explicitly commit after you perform a DML statement:
con.commit() # Assuming con is the name of the connection variable
I had no problem with SELECTing data in python from postgres database using cursor/execute. Just changed the sql to INSERT a row but nothing is inserted to DB. Can anyone let me know what should be modified? A little confused because everything is the same except for the sql statement.
<!-- language: python -->
#app.route("/addcontact")
def addcontact():
# this connection/cursor setting showed no problem so far
conn = pg.connect(conn_str)
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
sql = f"INSERT INTO jna (sid, phone, email) VALUES ('123','123','123')"
cur.execute(sql)
return redirect("/contacts")
first look at your table setup and make sure your variables are named right in the right order, format and all that, if your not logging into the specific database on the sql server it won't know where the table is, you might need to send something like 'USE databasename' before you do your insert statement so your computer is in the right place in the server.
I might not be up to date with the language but is that 'f' supposed to be right before the quotes? if thats in ur code that'd probably throw an error unless it has a use im not aware of or its not relevant to the problem.
You have to commit your transaction by adding the line below after execute(sql)
conn.commit()
Ref: Using INSERT with a PostgreSQL Database using Python
I have been learning sqlite3 in python and I was wondering if I could use string formatting to edit the database or query it.
e.g. - SELECT %s FROM (table_name) where % can be the users input stored in a variable?
I tried it but it doesn't work so can someone please give me a working example.
Any help is appreciated. Thanks
Guys i tried this:
dursor = conn.execute("SELECT id FROM books")
# this helps find the correct id for storing in the database
for i in dursor:
lis.append(i[0])
command = """INSERT INTO books VALUES ({0}, {name}, {author})""".format(lis[-1] + 1, name=client_name, author = client_author)
and then
conn.execute(command)
but it returns no such column (name)
when i tried the same query in khan academy sql it worked why not here?
You can place question mark on your query string and pass the parameters from user input while calling the .execute() as a tuple.
Though i don't believe you are using it in a production. If it is the case than first take the data from user, sanitize it and see if you really want to let the user do what he actually wants to do.
Hope this helps:
param1 = sys.argv[1]
param2 = sys.argv[2]
query = "SELECT ? FROM (table_name) where id = ?"
cursor.execute(query, (param1,param2))
I'm unsure if you can do it in sqlite3 but I'd be looking for any alternative method if I were you. Are you REALLY wanting to allow the user to be able to actually alter your SQL on the fly? That is a potentially huge security hole you'd be creating.
e.g. user can essentially alter...
select ? from innocentTable
...to...
select * from tblUser -- from innocentTable
...and trawl your entire user table, just takes a bit of guess work to come up with the object names.
I'd suggest you read up on SQL Injection Attacks then look for an alternative way to achieve what you've suggested.