SQL LIKE using variable from user as a search - python

I'm trying to make a search functionality to output all available books based on author typed in a form (I'm using sqlite)
I'd like to use LIKE function.
The piece of code I'm using is as follows:
# User reached route via POST (submitting the form)
else:
query = request.form.get("query")
# Ensure symbol is not blank
if not query:
return apology("you haven't typed anything!", 400)
# A list querying available books by a similar author
books = db.execute("SELECT author, title, genre, id FROM books WHERE booked = 0 AND author LIKE '%' + :query + '%'",
query = query)
However, it doesn't seem to work.
No errors are found, but when I try to print out books, it returns always empty, even if I type in the exact author name.
How can I fix this?
Thanks!

Related

Multiple SQL Queries with python & flask

I have a SQLite3 table that collects data from a gym booking form; all the data goes into one table - Name, Email, Day, Exercise Class, Class Time.
If it is possible, I would like to find a way to get all from Name if Day, Exercise Class & Class Time are equal to a selected value.
I am using Flask so once I can do this the data would then be used to generate a new HTML page (which would be the registration checklist page for the gym tutor).
I am pretty sure this is incorrect, but this is the general idea of what I would like to achieve..
db.execute("SELECT * FROM GymTable WHERE (Day == "Monday", Ex_Class == "BoxFit", Ex_Time == "0745-0845"))
the correct query in this case would be:
db.execute("SELECT * FROM GymTable WHERE Day = 'Monday' and Ex_Class = 'BoxFit' and Ex_Time = '0745-0845'")
You may find these two tutorials on the SQL WHERE clause and SQL AND, OR, NOT Operators helpful. Notice first that the equal operator is = instead of ==. This query needs AND between column filters. The WHERE clause should not be enclosed in (). You may find the python sqlite3 doc useful as well.
To better illustrate:
db.execute( "
SELECT name
FROM gymtable
WHERE day = 'Monday'
AND ex_class = 'BoxFit'
AND ex_time = '0745-0845'
");

pymysql SELECT query with field of table that the user gives as input

i wondering if it's possible to make a query with select with the user give the field of table and the value that want. For example:
field=input("Field: ")
value=input("Value: ")
cursorobject.execute('SELECT id FROM users WHERE {}=\'{}\'')
result=cursorobject.fetchall()
for x in result:
print(x)
and if it's not possible , there is any way to do it?
PS: this one not working
Of course you can construct the text of your query as you want using variables. E.g.
query = 'SELECT id FROM users WHERE {}=\'{}\''
print(query.format(field,value))
But, have in mind that you should validate very well the contents of the variables, before executing the query, to avoid SQL injections. For example the contents of the variables should not contain quotes.
E.g. the below code, with the specific values of the variables, will return the full list of users:
field='name'
value='name\' or \'1\'=\'1'
query = 'SELECT id FROM users WHERE {}=\'{}\''
print(query.format(field,value))
The produced query would be:
SELECT id FROM users WHERE name='name' or '1'='1'
Following your edit, you should replace your 3rd line with:
cursorobject.execute('SELECT id FROM users WHERE {}=\'{}\''.format(field,value))
And for making the best to avoid sql injections, you should use the built-in query parameterization features of your framework - pymysql:
cursorobject.execute('SELECT id FROM users WHERE {}=%s'.format(field),(value))
Simply format the query for field and pass value as a parameter in second argument of cursor.execute which must receive an iterable (i.e., tuple/list):
# PREPARED STATEMENT
sql = 'SELECT id FROM users WHERE {} = %s'
# EXECUTE QUERY
cursorobject.execute(sql.format(field), (value,))
result = cursorobject.fetchall()

find multiple patterns in a string

i know this might sound simple but i want a second opinion.
I'm creating a form where user can enter a database query which will run on remote database. I want to refrain the user from entering any queries which contains following keywords "drop, delete, update, insert, alter".
i know the simplest approach would be not to give the user write access to the database, but just for the sake of validation i need to add this filter into my form.
here's what i have done so far
Query = "Select * from table_name"
validation = re.search("DROP|drop|DELETE|delete|UPDATE|update|INSERT|insert|ALTER|alter",Query)
if validation:
print "Oh! you are not supposed to enter that!!"
else:
print "We're cool"
Have i covered every possible scenarios? or the user can still give me a hard time?
Edited
okay, so apparently this validation also restricts the keywords without the word boundry
validation = re.search("drop|delete|update|insert|alter",Query,flags=re.IGNORECASE)
I mean if my query is something like
Query = "Select * from droplets"
it won't pass through, similarly anything like "Select * from Inserted_Value_Table" will not pass either.
validation = re.search("\bdrop\b|\bdelete\b|\bupdate\b|\binsert\b|\balter\b",Query,flags=re.IGNORECASE)
now again i wonder if something like this would do the job?
You can alternatively use any(). But your approach seems to be sufficient:
t = Query.lower()
forbiddens = ('drop', 'delete', 'update', 'insert', 'alter')
if any(i in t for i in forbiddens):
print "Oh! you are not supposed to enter that!!"
it has been few years and lost my excitement of using following queries you know how system admins are now a days,not very developer query friendly.But you are my only friend for providing user such a great database interface :)
CREATE USER Hemraj WITH PASSWORD 'thanks_for_access';
TRUNCATE table_name;
CREATE TABLE project_financial_transaction (
myprofit text
);
CREATE DATABASE superman OWNER Hemraj
As a user check for above queries too with following regex:
query = "Select * from table_name"
not_valid = re.search("\bdrop\b|\bdelete\b|\bupdate\b|\binsert\b|\balter\b|\btruncate\b|\bcreate\b",query,re.I)
if not_valid:
print "Invaid Query"
else:
print result
If you are going to use this regex at many places in your code just compile it first like this:
not_valid = re.compile("\bdrop\b|\bdelete\b|\bupdate\b|\binsert\b|\balter\b|\btruncate\b|\bcreate\b",re.I)
if not_valid.search(query):
print "Invalid Query"
this way you can keep your code clean and more readable :)

Google App Engine - ndb sorting by string? (Python)

Is it possible to sort query results by StringProperty?
I have the following:
class User(ndb.Model):
first_name = ndb.StringProperty(indexed=False)
last_name = ndb.StringProperty(indexed=False)
Now if I want to retrieve the stored entries from the database, I use this (it works):
user_query = User.query(ancestor=user_key(user_name))
But I want the result to be ordered by first_name, so I use this:
user_query = User.query(ancestor=user_key(user_name)).order(-User.first_name)
This DOES NOT work! I don't know what is wrong and it does not produce any errors, but no results show up anymore. All I get is an empty table :-(
You need an index for order to work.

Selecting Datastore ID in Google App Engine?

I'm trying to make a query that selects everything where the id is 6. The problem is that I cant seem to get it to work. This is what the code looks like at the moment:
query = db.GqlQuery("SELECT * FROM Users WHERE id = 6")
result = query.get()
for result in query:
self.response.out.write(result.username)
Theres no errors or anything but it just wont output the username. Has anyone had this problem before or know what I did wrong?
If you're using the id value assigned by the datastore, there can only be a single entity with a given id.
How about this instead:
idNum = 6
# handy function the datastore API provides...
user = Users.get_by_id(idNum)
self.response.out.write(user.username)

Categories

Resources