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

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
);

Related

Entering data into specific field using "WHERE" in "INSERT" command in SQL? (Python)

I'm currently writing a program for a parents evening system. I have two tables, a bookings table and a teacher table - set up with the following column headings: TeacherSubject | 15:30 | 15:35 | 15:40 etc... When people make a booking, they select a teacher from a drop-down menu and also a time. Therefore, I need the bookingID added into the booking table where the teacher selected = to the same teacher in the table and where time selected = time in the database.
At the moment, my code only attempts to match the teacher, but this doesn't work as I'm getting the error of: (line 5)
TypeError: 'str' object is not callable
Am I doing the whole thing wrong and is this actually possible with the way I have set the table up?
def insert(parent_name, parent_email, student_name,student_form,teacher,app_time,comments):
conn=sqlite3.connect("parentsevening.db")
cur=conn.cursor()
cur.execute("INSERT INTO bookings VALUES (NULL,?,?,?,?,?,?,?)",(parent_name,parent_email,student_name,student_form,teacher,app_time,comments))
cur.execute("INSERT INTO teachers VALUES (?) WHERE teachers = (?)" (id,teacherName,))
conn.commit()
conn.close()
This SQL Query is invalid.
INSERT INTO teachers VALUES (?) WHERE teachers = (?)
It should be
INSERT INTO teachers (id, name) VALUES(?, ?)
Note that I'm guessing the teachers columns (id, name) WHERE on the insert isn't valid because it's used to find data (SELECT, UPDATE, DELETE)
OK, let's take out the comments and make this into an answer.
Python error
I think your error comes from WHERE teachers = (?) have you tried WHERE teachers = ? instead.
But...
bad sql syntax
Also that command as a whole doesnt make much sense, SQL syntax wise - you seem to be trying to insert where a teacher that doesn't exist (if you are inserting them) and values on an insert does not go with where and where needs a from. i.e. once you've solved your python error, sqlite is going to have a fit as well.
That's already covered by another answer.
But...
probably not what you should be doing
If you have an existing teacher, you only need to insert their teacherid into table bookings. You don't have to, and in fact, you can't insert into table teachers at this point, you'd get a duplicate data error.
So, rather than fixing your second query, just get rid of it entirely.
If you can get a command line or GUI SQL tool up, try running these queries by hardcoding them by hand before coding them in Python. the sqlite command should be able to do that for you.
(recommendation) don't use insert table values
Try being explicit with insert into table (<column list>) values .... The reason is that, as soon as the table changes in some way that affects column order (possibly an alter column) the values won't line up with the implied insert list. hard to debug, hard to know what was intended at time of writing. Been there, done that. And had to debug buncha folks' code who took this shortcut, it's never fun

Unable to see table after creation in Flask-sqlalchemy [duplicate]

When I make a MySQL table order, it is created successfully but, when I execute any query against it, it says "error 1064 , syntax error".
When I change the name to orders, it works fine.
But I don't want to change the name. How can I execute our query against the order table?
can you use something like?
select * from `order`
The word order is actually an SQL keyword. You would have the same problem if you tried to use a table called group or select. You can fix it is MySQL by using quotes around it, along the lines of:
select f1, f2 from `order` where blah blah blah ...
However, unless your table will only ever hold a single order (in which case it won't do so for long since the underlying business will soon be bankrupt), you should probably call your table orders.
That solves both your problems, the one you found and the one you didn't :-)
I got here because I was searching for similar solution for SQL CE. There using
order
'order'
"order"
doesn't work.
What worked was:
[order]
Maybe it'll help someone else also.
This should fix the problem:
e.g
mysql>
Create table order(
ID char(5),
QTY(3)
)
;

Strange SQL statement error in SQLAlchemy-Flask

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?

Error on simple MySQL query using Python, but works in MySQL console?

I'm trying to run a simple insert query to a database. I have it configured correctly, and it should work, but it doesn't. For some reason I get the following error on this query:
Query:
INSERT INTO searches (query) VALUES ('test')
Error:
(1062, "Duplicate entry 'test' for key 'query'")
The query runs without problems in the MySQL console so it must be a problem with Python? Here's my Python code:
def increase_search_count(search_query):
from django.db import connection, transaction
search_query = search_query.strip()
cursor = connection.cursor()
rows = cursor.execute("INSERT INTO searches (query) VALUES ('test')")
I know there are much better ways to handle databases, but I'm new to Python, and I have a deadline. I'd just like to get this to work, I have another SELECT query in another function and that one runs without any problems!
Any ideas what might be wrong?
The way that query is constructed means you will always be inserting 'test' into the database, and seeing the query is likely the primary key in your table, it will be creating duplicate rows.
The query should be something like "INSERT INTO searches (query) VALUES ('" variable "')" so you don't insert the same value over and over.

lastrowid() alternative or syntax without using execute in sqlite python?

In sqlite3 in python, I'm trying to make a program where the new row in the table to be written will be inserted next, needs to be printed out. But I just read the documentation here that an INSERT should be used in execute() statement. Problem is that the program I'm making asks the user for his/her information and the primary key ID will be assigned for the member as his/her ID number must be displayed. So in other words, the execute("INSERT") statement must not be executed first as the ID Keys would be wrong for the assignment of the member.
I first thought that lastrowid can be run without using execute("INSERT") but I noticed that it always gave me the value "None". Then I read the documentation in sqlite3 in python and googled alternatives to solve this problem.
I've read through google somewhere that SELECT last_insert_rowid() can be used but would it be alright to ask what is the syntax of it in python? I've tried coding it like this
NextID = con.execute("select last_insert_rowid()")
But it just gave me an cursor object output ""
I've also been thinking of just making another table where there will always only be one value. It will get the value of lastrowid of the main table whenever there is a new input of data in the main table. The value it gets will then be inserted and overwritten in another table so that every time there is a new set of data needs to be input in the main table and the next row ID is needed, it will just access the table with that one value.
Or is there an alternative and easier way of doing this?
Any help is very much appreciated bows deeply
You could guess the next ID if you would query your table before asking the user for his/her information with
SELECT MAX(ID) + 1 as NewID FROM DesiredTable.
Before inserting the new data (including the new ID), start a transaction,
only rollback if the insert failes (because another process was faster with the same operation) and ask your user again. If eveything is OK just do a commit.
Thanks for the answers and suggestions posted everyone but I ended up doing something like this:
#only to get the value of NextID to display
TempNick = "ThisIsADummyNickToBeDeleted"
cur.execute("insert into Members (Nick) values (?)", (TempNick, ))
NextID = cur.lastrowid
cur.execute("delete from Members where ID = ?", (NextID, ))
So basically, in order to get the lastrowid, I ended up inserting a Dummy data then after getting the value of the lastrowid, the dummy data will be deleted.
lastrowid
This read-only attribute provides the rowid of the last modified row. It is only set if you issued an INSERT statement using the execute() method. For operations other than INSERT or when executemany() is called, lastrowid is set to None.
from https://docs.python.org/2/library/sqlite3.html

Categories