psycopg2 sql.SQL how to implement timestamp > now() - INTERVAL '8 days'? - psycopg2

I want to select records newer than 8 days from several tables. This is not working:
self._getRawData = sql.SQL("SELECT * FROM {} WRERE {} > NOW() - INTERVAL {}")
...
cur = self._conn.cursor()
cur.execute(self._getRawData.format(sql.Identifier('MyTS.MyTable'), \
sql.Identifier('Timestamp'), \
sql.Identifier('8 days')))
gives error:
psycopg2.errors.SyntaxError: syntax error at or near ""Timestamp""
Below is working OK, but I want to implement sql.SQL for several tables. Any advice?
statement = "SELECT * FROM \"MyTS\".\"MyTable\" WHERE \"Timestamp\" > NOW() - INTERVAL \'8 days\'"
cur = self._conn.cursor()
cur.execute(statement)
Update: Thanks to the comments, I solved it with
self._getRawData = sql.SQL("SELECT * FROM {}.{} WHERE {} > NOW() - INTERVAL {}")
...
sql.Literal('8 days')))

Related

Influx subquery returns no results

I'm experimenting with subqueries in InfluxDB (shell version: 1.7.4), and I've encountered this issue:
> SELECT "value" AS "legacy" FROM my_table WHERE time >= '2022-12-22 18:00:00' AND entityId = '637deee12ccd09000b8bea57' tz('Europe/Athens')
name: my_table
time legacy
---- ------
2022-12-22T18:15:16.261+02:00 11
2022-12-22T19:15:30.65+02:00 12
> SELECT * FROM (SELECT "value" AS "legacy" FROM my_table WHERE time >= '2022-12-22 18:00:00' AND entityId = '637deee12ccd09000b8bea57' tz('Europe/Athens'))
>
> SELECT SUM(*) FROM (SELECT "value" AS "legacy" FROM my_table WHERE time >= '2022-12-22 18:00:00' AND entityId = '637deee12ccd09000b8bea57' tz('Europe/Athens'))
>
The second and third queries, both return an empty result. I would expect the second to return the same result as the first one, and the third to return the sum. What have I misunderstood?

Pyspark date intervals and between dates?

In Snowflake/SQL we can do:
SELECT * FROM myTbl
WHERE date_col
BETWEEN
CONVERT_TIMEZONE('UTC','America/Los_Angeles', some_date_string_col)::DATE - INTERVAL '7 DAY'
AND
CONVERT_TIMEZONE('UTC','America/Los_Angeles', some_date_string_col)::DATE - INTERVAL '1 DAY'
Is there a pyspark translation for this for dataframes?
I imagine if something like this
myDf.filter(
col(date_col) >= to_utc_timestamp(...)
)
But how can we do BETWEEN and also the interval?
You can use INTERVAL within SQL expression like this:
df1 = df.filter(
F.col("date_col").between(
F.expr("current_timestamp - interval 7 days"),
F.expr("current_timestamp - interval 1 days"),
)
)
However if you only filter using days, you can simply use date_add (or date_sub) function:
from pyspark.sql import functions as F
df1 = df.filter(
F.col("date_col").between(
F.date_add(F.current_date(), -7),
F.date_add(F.current_date(), -1)
)
)

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

Pandas Oracle query gives "ORA-00911: invalid character"

Hello I am trying to execute the following Oracle Query. I confirmed i can successfully connect to the database using cx_Oracle but my query is not executing. This is a large table and i am trying to limit the number of rows to 10
query1 = """
select *
from
(select *
from some_table
)
where rownum < 10;
"""
df_ora1 = pd.read_sql(query1, con=connection1)
I am getting the following error but cant figure out what the invalid character is!
DatabaseError: ORA-00911: invalid character
Please help!
Remove the semi-colon from the SQL statement. Semi-colons are not part of SQL.
query1 = """ select * from (select * from some_table ) where rownum < 10 """

InfluxDB composite query

Why this function don't bring the results? In influxdb.
select * from items.movement
where time > now() - 7d
and oldContainerId='aaaaaa'
and newContainerId='aaaaaaa'
Thanks.
I solved with this:
select * from series
where time > now() - 7d
and newContainerId = 'aaaa'
limit 100;
select * from series
where time > now() - 7d
and oldContainerId = 'aaaa'
limit 100
select * from "items.movement" where time > now() - 7d and oldContainerId = 'aaaaaa' and newContainerId = 'aaaaaaa'
NOTE : Space and double quotes matters.

Resources