Reputation: 897
I have a table in SQLite. As expected, I can access to this with a WHERE variable.
import sqlite3
name = 'john'
age = 16
conn = sqlite3.connect('AmApp.db')
sql = """SELECT * FROM clients WHERE first_name='{}' AND age={}""".format(name, age)
df = pd.read_sql_query(sql, conn)
print (df)
However, if either name or age was empty then this does not work. Whilst this can be worked around this manually, my intention is that age and name are user inputs. Therefore how would I set this so that the WHERE statements do not filter is there is nothing to filter on?
Upvotes: 0
Views: 226
Reputation: 30679
A standard way to create dynamic sql queries are case
statements, although the query becomes a bit hard to read:
import pandas as pd
import sqlite3
conn = sqlite3.connect("DataSource=:memory:;Version=3;New=True;")
create_table=""" CREATE TABLE IF NOT EXISTS clients (
id integer PRIMARY KEY,
first_name text NOT NULL,
age integer
)"""
c = conn.cursor()
c.execute(create_table)
c.execute("insert into clients(id,first_name,age) values(1,'john',16)")
c.execute("insert into clients(id,first_name,age) values(2,'tom',20)")
c.execute("insert into clients(id,first_name,age) values(3,'tom',16)")
name = 'john'
age = 16
sql = f"""SELECT * FROM clients WHERE
case when '{name}' = '' then 1 else first_name end = case when '{name}' = '' then 1 else '{name}' end AND
case when {age} = 0 then 1 else age end = case when {age} = 0 then 1 else {age} end"""
df = pd.read_sql_query(sql, conn)
print(df)
Examples:
name = 'john'
age = 16
id first_name age
0 1 john 16
name = ''
age = 16
id first_name age
0 1 john 16
1 3 tom 16
name = 'tom'
age = 0
id first_name age
0 2 tom 20
1 3 tom 16
name = ''
age = 0
id first_name age
0 1 john 16
1 2 tom 20
2 3 tom 16
sql = "SELECT * FROM clients WHERE 1"
if name != '':
sql += f" AND first_name='{name}'"
if age > 0:
sql += f" AND age={age}"
Upvotes: 0
Reputation: 164214
One way of doing this is to introduce 2 new parameters, one for each of the name
and age
, that denote whether that column will be filtered or not, combined with the operator OR
with the corresponding column:
sql = """SELECT * FROM clients WHERE (first_name='{}' OR 0={}) AND (age={} OR 0={})""".format(name, filterbyname, age, filterbyage)
These new parameters will have values 0
or 1
.
Examples:
Both values 1 and valid values for name
and age
:
filterbyname = 1
name = 'john'
filterbyage = 1
age = 16
For filterbyname
the value 1
and valid value for name
and for filterbyage
the value 0
and any vale for age
(filter only by name):
filterbyname = 1
name = 'john'
filterbyage = 0
age = 0
For filterbyage
the value 1
and valid value for age
and for filterbyname
the value 0
and any vale for name
(filter only by age
):
filterbyname = 0
name = ''
filterbyage = 1
age = 25
If you want to return all the rows of the table without filtering:
filterbyname = 0
name = ''
filterbyage = 0
age = 0
Upvotes: 1