The problem:
I am working on a bit of code that is meant to create a new record in a linking table. The linking table has a primary key that is an auto number, the other two fields are VARCHAR with a length of 10.
The issue I'm having is I cannot seem to get partID into the table. If you look at the sql output you can clearly see it write None and u'1' (the orderID) to the table. So that tells me its recieving the orderID just fine. Also you can see that I did a print to find out what is inside my variable before passing it to the new object. It has 3 in it which is the correct partId. Somewhere between creating the new object and writing to the table it passes a null.
I've tried to cast it, Ive tried different ways of pulling the partID from the database, etc and I cannot for the life of me figure out what is wrong.
The code:
def updateOrderParts_view(request):
part = None
partToOrder = None
idnum = None
part = DBSession.execute(\
"SELECT partID "+\
"FROM tblParts "+\
"WHERE partName = " + "'" +request.POST['partName'] +"'").fetchone()
print "<---DEBUG--->"
print part['partID']
partToOrder = PartsByOrder(part['partID'], request.POST['orderID'])
DBSession.add(partToOrder)
return{}
The terminal output:
<---DEBUG--->
3
2013-04-24 08:14:47,985 INFO [sqlalchemy.engine.base.Engine][Dummy-2] INSERT INTO "tblPartsByOrder" ("partID", "orderID") VALUES (?, ?)
2013-04-24 08:14:47,985 INFO [sqlalchemy.engine.base.Engine][Dummy-2] (None, u'1')
2013-04-24 08:14:47,986 INFO [sqlalchemy.engine.base.Engine][Dummy-2] COMMIT
I would appreciate any thoughts or comments on this issue
Thanks for your time
First, I would look at doing the SQL lookup a little different, if you can. (I guess it depends, do you have a model based on "tblParts"? I'm going to use an example assuming there is a model object "Part"):
part = DBSession.query(Part.partID).filter(Part.partName == request.POST['partName']).first()
From there, I'm rusty on the exact syntax but I think you could do something like
print "<---DEBUG--->"
print part
partToOrder = PartsByOrder(part, request.POST['orderID'])
DBSession.add(partToOrder)
return{}
You might need to case "part" to a string (str(part)) if it's a casting problem.
Good luck,
Related
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 have another question that is related to a project I am working on for school. I have created a PostgreSQL database, with 5 tables and a bunch of rows. I have created a script that allows a user to search for information in the database using a menu, as well as adding and removing content from one of the tables.
When displaying a table in PostgreSQL CLI itself, it looks pretty clean, however, whenever displaying even a simple table with no user input, it looks really messy. While this is an optional component for the project, I would prefer to have something that looks a little cleaner.
I have tried a variety of potential solutions that I have seen online, even a few from stack overflow, but none of them work. Whenever I try to use any of the methods I have seen and somewhat understand, I always get the error:
TypeError: 'int' object is not subscriptable
I added a bunch of print statements in my code, to try and figure out why it refuses to typecast. It is being dumb. Knowing me it is probably a simple typo that I can't see. Not even sure if this solution will work, just one of the examples I saw online.
try:
connection = psycopg2.connect(database='Blockbuster36', user='dbadmin')
cursor = connection.cursor()
except psycopg2.DatabaseError:
print("No connection to database.")
sys.exit(1)
cursor.execute("select * from Customer;")
tuple = cursor.fetchone()
List_Tuple = list(tuple)
print("Customer_ID | First_Name | Last_Name | Postal_Code | Phone_Num | Member_Date")
print(List_Tuple)
print()
for item in List_Tuple:
print(item[0]," "*(11-len(str(item[0]))),"|")
print(item)
print(type(item))
print()
num = str(item[0])
print(num)
print(type(num))
print(str(item[0]))
print(type(str(item[0])))
cursor.close()
connection.close()
I uploaded the difference between the output I get through a basic python script and in the PostgreSQL CLI. I have blocked out names in the tables for privacy reasons. https://temporysite.weebly.com/
It doesn't have to look exactly like PostgreSQL, but anything that looks better than the current mess would be great.
Use string formatting to do that. You can also set it to pad right or left.
As far as the dates use datetime.strftime.
The following would set the padding to 10 places:
print(”{:10}|{:10}".format(item[0], item[1]))
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.
Not sure if I phrased the title correctly, but basically my question is is it possible to have sqlite update a row which is defined by a variable? For example:
db.execute('''UPDATE CUSTOMER SET ? = ? WHERE CUSTOMER_ID = ?''', (title, info.get(), k))
where 'title' (the first question mark) is the name of the 'row' I want to update within the table Customer. I have tried the above code but it doesn't work. Does anybody know if it is possible to do this with sqlite3 in any way?
SQL parameters are designed to never be interpretable as SQL objects (like column names); that is one of their major usecases. If they didn't they wouldn't prevent SQL injection attacks. Instead, the title value is either properly escaped as a value, or rejected altogether as the syntax doesn't allow a value in that location.
As such, you need to make sure that your title variable is a proper SQL object name (never take user input directly here) and use string formatting for just that value:
db.execute(
'''UPDATE CUSTOMER SET {} = ? WHERE CUSTOMER_ID = ?'''.format(title),
(info.get(), k))
You probably want to match title against a pre-defined set of possible column names first.
Can you try like this
query = "UPDATE CUSTOMER SET %s = '%s' WHERE CUSTOMER_ID = %d" %(title, info.get(), k)
db.execute(query)
May be you need to commit it.