I have a quest to do that is about searching a product (table) just by one or more letters and come up the columns that I want (name, description and type) but i have a problem on using the keyword... i know it should be a string but i can't figure out a way to do it. Right now i have this
@app.route('/product/<keyword>', methods=['GET'])
def product_search(kw):
logger.info('GET /product/<keyword>')
logger.debug(f'keyword: {kw}')
conn = db_connection()
cur = conn.cursor()
try:
cur.execute('SELECT id, type, name, price from product where name like s% or type like s% or description like %s', (kw,))
rows = cur.fetchall()
row = rows[0]
logger.debug('GET /product/{keyword} - parse')
logger.debug(row)
content = {'id': int(row[0]), 'type': row[1], 'name': row[2], 'price': row[3], 'description': row[5]}
response = {'status': StatusCodes['success'], 'results': content}
except (Exception, psycopg2.DatabaseError) as error:
logger.error(f'GET /product/{keyword} - error: {error}')
response = {'status': StatusCodes['internal_error'], 'results': str(error)}
finally:
if conn is not None:
conn.close()
return flask.jsonify(response)
And i also wanted to know i could i put on the
cur.execute('SELECT id, type, name, price from product where name like s% or type like s% or description like s%
%s', (kw,))
a way to basically execute the program but doing it for example using the letter c to search a product like coke or something
'SELECT id, type, name, price from product where name like '%c' or type like '%c' or description like '%c%'
in other words i want it in the name and type just to search by the first letter and the description by the middle of the sentence. I'm new in postgres sql so sorry for some wrong knowledge :)
CodePudding user response:
The correct way to interpolate values into SQL queries in Python is to use parameter substitution, as you are already doing, for example:
values = ('Alice', 'Bob')
cur.execute("""SELECT name FROM tbl WHERE name = %s OR name = %s""", values)
The values are correctly quoted by the connector to minimise the risk of errors and of SQL injection. Using string formatting techniques to do this is error prone and not recommended.
To handle values for LIKE
queries, you need to append or prepend the "%" characters to the values, like this:
values = (kw '%',)
cur.execute("""SELECT id, type, name, price from product where name like %s""", values)
If you want to use the same value in multiple places, you can use a dictionary of values instead of a tuple:
values = {'kw': kw '%', 'kw2': '%' kw '%'}
cur.execute("""SELECT id, type, name, price from product where name like %(kw)s or type like %(kw)s or description like %(kw2)s""", values)
Note that it's OK to build the values themselves using string formatting, like this
values = (f'{kw}%',)
cur.execute(sql, values)
but it is not OK to use string formatting to place the values into the query itself:
# Not OK
cur.execute(f"""SELECT * FROM tbl WHERE name = {kw}""")
CodePudding user response:
You should use the same name in function input parameters as in url, it you do so it will be str already:
@app.route('/product/<keyword>', methods=['GET'])
def product_search(keyword):
print(type(keyword)) # <class 'str'>