Strange SQL statement error in SQLAlchemy-Flask - python

I am using SQLAlchemy in Flask to connect to my Postgres server, and now I want to execute some raw SQL to insert a column into a table. I am getting this error, however:
sqlalchemy.exc.ProgrammingError: (ProgrammingError) syntax error at or near "user"
LINE 1: ALTER TABLE user ADD COLUMN permissions INTEGER
^
'ALTER TABLE user ADD COLUMN permissions INTEGER' {}
As you can see, it says there is an SQL error, although I have no idea what I could be doing wrong.
This is the very simple function that executes the command:
#staticmethod
def addColumn():
db.engine.execute('ALTER TABLE user ADD COLUMN permissions INTEGER')
The db object otherwise works perfectly, and there is nothing wrong with the connection or anything of the sort.
I feel like I'm overlooking something very simple, but I just can't figure out what it is. Does anybody have any idea?

The PostgreSQL docs say that USER is a reserved keyword, and needs to be quoted to be used as an identifier.
Key Word PostgreSQL SQL 99 SQL 92
USER reserved reserved reserved

Is user a reserved word and thus needing to be referenced specially in SQL statement?

Related

Error while creating tables in mysql.connector python -- syntax error code 1064(4200)

c1.execute(f"create table {sub_table_name1}(srno int, data_name varchar(255), data varchar(255))")
the error is
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(srno int, data_name varchar(255), data varchar(255))' at line 1
i swear to god i have no idea what is wrong...i'm still a beginner to python and mysql connection and any help is welcome
What is the value of your sub_table_name1 variable at the time you execute that? If it's empty, then I think that error would be expected, because the SQL statement would be:
create table (srno int, ...
MySQL will see that as a missing name. The way it informs you of the error is to tell you the part of the query at the point it got confused:
for the right syntax to use near '(srno int, ...
This means when it saw (srno int, ... it was expecting something else — I'm guessing it was expecting an identifier for the name of the table, but reached the open parenthesis character instead.
Since you said you are new to python (and perhaps to programming), here's a general tip: question your assumptions. You assumed the create table statement had a table name in it. Does it? How would you know? Can you add code to print the SQL statement string after you format it with the variables? Can you add code to print the sub_table_name1 variable before using it in the string? Of course, you should remove such code after you are done debugging.
"The most effective debugging tool is still careful thought, coupled
with judiciously placed print statements."
— Brian Kernighan, "Unix for Beginners" (1979)
That's an old book, but the idea is still true!

MYSQL parameter python issue with table name

I am new in using python API to send a query to mysql.
My issue is very easy to reproduce. I have a table named "ingredient" and I would like to select the rows from python using parameters
If I do cursor.execute("select * from ?",('ingredient',)) I get the error message : Error while connecting to MySQL Not all parameters were used in the SQL statement MySQL connection is closed
I I do cursor.execute("select * from ?",'ingredient') I get the error message : Error while connecting to MySQL 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1
Same issues using %s instead of ?. Using the other type of single quote on 'ingredient' instead of 'ingredient' does not give results either.
How is this supposed to work here ?
You just can't pass a table name as parameter to a query. The parameterization mechanism is there to pass literal values, not object names. Keep in mind that the database must be able to prepare the query plan from just the parameterized string (without the actual parameter value), which disqualifies using metadata as parameter.
You need string concatenation instead:
cursor.execute("select * from " + yourvar);
Note that, if the variable comes from outside your program, using such contruct exposes your code to SQL injection. You need to manually validate the value of the parameter before execting the query (for example by checking it against a fixed list of allowed values, or by querying the information schema of the database to ensure that the table does exist).
Does your query work if you just write:
cursor.execute("SELECT * FROM ingredient")
?

Creating single query with subquery, essentially a insert query with select query

I've created a login function with flask, it consists of a code that opens a connection to the database then selecting a username based on the inputed username. To be more precise, here's the query:
cursor.execute("""
SELECT username FROM user_tbl
WHERE username = %s""",
(self.username))
After that, I check the length of the fetched data, if length is 0 then I open up another connection then perform an insert query, like so:
cursor.execute("""
INSERT INTO
user_tbl(username,password,email,user_type)
VALUES(%s,%s,%s,%s)""",
(self.username,self.password,self.email,self.user_type))
I've been doing this process since coding with PHP and would like to confirm if there is any way to combine these two queries. I've been researching like crazy and can't seem to find the answer... or atleast answers that work.
MySQL direct INSERT INTO with WHERE clause based on the accepted answer there, INSERT INTO...SELECT is the way to go, however after looking into it its mostly about transferring data from another table to another, I am targeting one table (my apologies if I'm missing something ).
I can't find the link, however I found another answer that mentioned that the only time you'll see a WHERE clause in an INSERT query(aside from the answer I posted above) is when you're checking if nothing 'EXISTS' (which makes sense and based on that answer I made the conclusion that having a where clause in an insert query is ok).
After checking up subquerying on a WHERE clause and following examples in this link: https://www.essentialsql.com/get-ready-to-learn-sql-server-21-using-subqueries-in-the-where-clause/ I've created my own query:
INSERT INTO user_tbl(username,password,email,user_type)
VALUES("test.test","test","test","test")
WHERE username IN
(SELECT username FROM user_tbl WHERE username="test.test");
Reason why I chose IN is because, as mentioned in the link, once a subquery returns NULL, IN returns false for the WHERE clause (at least that's how I interpreted it).
Unfortunately, each time I run this code on my terminal I get this syntax error:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE username IN (SELECT username FROM user_tbl WHERE username="test.test")'
Hence the title, Can you guys please explain how exactly is my code syntactically wrong? Also, can you perchance pinpoint me to the right direction as I am very lost on this.
Thanks in advance,
Inno
I understand that you want to INSERT a new record in user_tbl only if it does not yet exist.
MysQL has a special syntax for that, called INSERT ... ON DUPLICATE KEY UPDATE.
For this to work, you need column username to be the primary key in your table (or to have a UNIQUE constraint).
Then you can simply do:
cursor.execute(
"""
INSERT INTO user_tbl(username,password,email,user_type)
VALUES(%s,%s,%s,%s)
ON DUPLICATE KEY UPDATE username = VALUES(username)
""",
(self.username,self.password,self.email,self.user_type)
)
If no record aleady exists for the given username, a new record is created. Else, the UPDATE clause is invoked (here, that would simply reassign the same value to the username , which is basically a no-op).
you cant use the same table, but you can "hide" the SELECT then MySQL did not see this like:
INSERT INTO user_tbl(username,password,email,user_type)
VALUES("test.test","test","test","test")
WHERE username IN
(SELECT * FROM (
SELECT username FROM user_tbl WHERE username="test.test"
) as myuser
);

sql INSERT in python (postgres, cursor, execute)

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

Prevent MySQL-Python from inserting quotes around database name parameter

I'm working on a project that requires me to programmatically create MySQL users from a django app. I can create the users just fine:
from django.db import connection, transaction
cursor = connection.cursor()
cursor.execute("CREATE USER %s#'%'", 'username')
cursor.execute("SET PASSWORD FOR %s#'%' = PASSWORD(%s)", ('username', 'pass'))
That works perfectly. The problem is when I try to grant permissions. The database name is also determined programmatically:
cursor.execute("GRANT SELECT ON %s.* TO %s#'%'", ('dbname', 'username'))
This results in a mysql error because when it does the string substitution, it places single quotes around the database name, which is syntactically incorrect:
DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''dbname'.* to 'username'#'%'' at line 1")
How do I prevent the single quotes from being added around the %s for database name? I know that I could simply do the string substitution in Python and fix this, but that could potentially cause a SQL injection vulnerability.
Sometimes placeholders won't work (as you've found out), so you'll have to use string concatenation. Be careful - validate the string, make sure it's only composed of the characters you expect (don't just look for characters you don't expect), and you should be OK. Also get another developer to check your code, and comment it to make sure no-one else thinks you ought to be using placeholders.

Categories