sqlite3 variable substitution not working python3 - python-3.x

I'm trying to get the SQLlite3 variable substitution in Python working, but I always get the error:
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 0, and there are 1 supplied.
I've tried:
date_range = '10'
with sqlite3.connect(DATABASE_LOGIN) as connection:
cursor = connection.cursor()
template = "SELECT DISTINCT date FROM schedule WHERE date BETWEEN DATETIME('NOW') AND DATETIME('NOW', '-? DAYS') ORDER BY date"
cursor.execute(template, date_range)
and I know it's very bad form to use:
date_range = '10'
with sqlite3.connect(DATABASE_LOGIN) as connection:
cursor = connection.cursor()
template = f"SELECT DISTINCT date FROM schedule WHERE date BETWEEN DATETIME('NOW') AND DATETIME('NOW', '-{date_range} DAYS') ORDER BY date"
cursor.execute(template)
but for some reason the former query doesn't work.

You must concatenate the placeholder ?:
SELECT DISTINCT date
FROM schedule
WHERE date BETWEEN DATETIME('NOW') AND DATETIME('NOW', '-' || ? || ' DAY') ORDER BY date

Related

Delete a record from SQLite database WHERE datetime contains date from variable

I want to DELETE every record with a datetime (e.g. 2022-11-10T??????????) using a date (e.g. 2022-11-10) from a variable. For example:
last_Date = datetime.strftime(datetime.now() - timedelta(1), '%Y-%m-%d')
And use SQL like this:
cursor.execute("""
DELETE FROM alpaca_stock_prices_4H WHERE datetime = (?)
""", (last_Date))
The value of the variable last_Date is a formatted as YYYY-MM-DD date string but the column datetime in the table contains timestamps in the format YYYY-MM-DDT?????????? so you can't compare them with the = operator.
Use SQLite's strftime() or date() function to format the datetimes also to YYYY-MM-DD:
cursor.execute("""
DELETE FROM alpaca_stock_prices_4H WHERE strftime('%Y-%m-%d', datetime) = ?
""", (last_Date,))
or:
cursor.execute("""
DELETE FROM alpaca_stock_prices_4H WHERE date(datetime) = ?
""", (last_Date,))
If what you actually want is delete all yesterday's rows you can do it without passing a parameter, by using only SQL code:
cursor.execute("""
DELETE FROM alpaca_stock_prices_4H WHERE date(datetime) = date('now', '-1 day'))
""")

how to compare datetime using psycopg2 in python3?

I wish to execute the statement to delete records from a postgresql table older than 45 days in my python script as below:
Consider only the code below:
import psycopg2
from datetime import datetime
cur = conn.cursor()
mpath = None
sql1 = cur.execute(
"Delete from table1 where mdatetime < datetime.today() - interval '45 days'")
This causes the following error:
psycopg2.errors.InvalidSchemaName: schema "datetime" does not exist
LINE 1: Delete from logsearch_maillogs2 where mdatetime <
datetime.t...
How do I exactly change the format or resolve this. Do I need to convert. Saw a few posts which say that postgresql DateTime doesn't exist in PostgreSQL etc, but didn't find exact code to resolve this issue. Please guide.
The query is running in Postgres not Python you need to use SQL timestamp function not Python ones if you are writing a hard coded string. So datetime.today() --> now() per Current Date/time.
sql1 = cur.execute(
"Delete from table1 where mdatetime < now() - interval '45 days'")
Or you need to use parameters per here Parameters to pass in a Python datetime if you want a dynamic query.
sql1 = cur.execute(
"Delete from table1 where mdatetime < %s - interval '45 days'", [datetime.today()])

How to pass param inside single quotes to a postgres query?

In my node app, i need to run below query and and i'm passing parameters dynamically. But it's not fetching the parameters since they are referenced inside single quotes. Suggest a solution for this.
const text = `UPDATE glacier_restore_progress
SET
status='completed',
restore_end=CURRENT_TIMESTAMP,
restore_expire=DATE_TRUNC('minutes', current_timestamp + interval '$1 minutes')
WHERE file_path = '$2' AND date_trunc('minutes', current_timestamp - interval '$1 minutes') <= restore_start`;
const values = [restoreDuration, fileKey];
await pool.query(text, values);
and the error i get is,
"bind message supplies 2 parameters, but prepared statement \"\" requires 0"
You are absolutely right; parameters cannot be inside quotes. There are a few ways we can solve this:
Taking the similarly broken example SELECT * FROM employees WHERE CURRENT_TIMESTAMP - start_date < INTERVAL '$1 years';
Have the client submit the "full" value: SELECT * FROM employees WHERE CURRENT_TIMESTAMP - start_date < INTERVAL $1;
Construct string in the query: SELECT * FROM employees WHERE CURRENT_TIMESTAMP - start_date < INTERVAL ($1 || ' years');
(interval specific) Use the fact the unit can be specified as its own keyword: SELECT * FROM employees WHERE CURRENT_TIMESTAMP - start_date < INTERVAL $1 MINUTE
My preference in this case is 1, however the most faithful to your question is 3. Be careful to use MINUTE and not MINUTES. Option 2, using the concatentation operator, is a good hack to have in your toolbelt. All answers tested in Postgres 13.
In addition to this, your parameter is likely going to bound as a number, which will get you an error. You may need to cast it to text, like so $1::TEXT
Your full query would be:
UPDATE glacier_restore_progress
SET
status = 'completed',
restore_end = CURRENT_TIMESTAMP,
restore_expire = DATE_TRUNC('minutes', CURRENT_TIMESTAMP + INTERVAL $1::TEXT MINUTE)
WHERE file_path = $2
AND DATE_TRUNC('minutes', current_timestamp - INTERVAL $1 MINUTE) <= restore_start
use this,
const text = `UPDATE glacier_restore_progress
SET
status='completed',
restore_end=CURRENT_TIMESTAMP,
restore_expire=DATE_TRUNC('minutes', current_timestamp + interval '1 minutes' * $1)
WHERE file_path = $2 AND date_trunc('minutes', current_timestamp - interval '1 minutes' * $1) <= restore_start`;
const values = [restoreDuration, fileKey];
await pool.query(text, values);
this convention is mentioned here refrence

Read file with Python while passing arguments

I'm trying to read a file with this argument {year} inside it.
Inside this file there is this string:
SELECT * FROM TABLE WHERE YEAR = {year}
I'd like to read this file with Python f-strings to use the query after.
The expected result looks like this:
SELECT * FROM TABLE WHERE YEAR = 2019
I tried this:
year = 2019
with open("test.sql") as query_file:
query = query_file.read()
print(query)
But the output was SELECT * FROM TABLE WHERE YEAR = {year} instead of SELECT * FROM TABLE WHERE YEAR = 2019
I have no idea how I can put the year variable to replace the {year} inside the file.
Use str.format to replace the {year}.
f-strings are literals and must be an expression. Python will not replace data in string, just because there is a variable of the same name in the bracket notation.
query = 'SELECT * FROM TABLE WHERE YEAR = {year}'
query.format(year=2019)
Edit:
To replace values in a SQL query it's better and more secure to use prepared statements like:
c = db.cursor()
year = 2019
c.execute("SELECT * FROM TABLE WHERE YEAR = %s;", (year,))
See also the examples of MySQLdb

Update date column to current date

i have created a column for date using workbench now i have to update all the values of that column to current date either using sql query or using python code
mydb = mysql.connector.connect(host="localhost", user="root",
password="afif123", db="library")
mycursor = mydb.cursor()
fill = '''UPDATE issued_book SET Today = current_date()'''
mycursor.execute(fill)
#or
today = datetime.datetime.now()
fill = '''UPDATE issued_book SET Today = %s'''
mycursor.execute(fill, [today])
any of above two attempt doesn't helping
i have kept datatype of date column as DATETIME()
To do it in mysql, just modify your first query a bit...
update issued_book set today = now()
instead of current_date(), which is not a mysql function.

Resources