Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlAlchemy temporal operations not properly handled #33

Open
Aramos93 opened this issue Nov 4, 2021 · 1 comment
Open

SqlAlchemy temporal operations not properly handled #33

Aramos93 opened this issue Nov 4, 2021 · 1 comment

Comments

@Aramos93
Copy link

Aramos93 commented Nov 4, 2021

Correct me if i'm completely misusing this but I'm trying to perform a simple "meets" expression as cql-json:

For simplicity my db contains the following datetimes:

1: 2019-06-24T07:41:10Z
2: 2019-06-24T07:41:13Z
3: 2019-06-24T07:41:17Z
4: 2019-06-24T07:41:21Z

And I want to perform a "meets" request with time interval 2019-06-24T07:41:13 - 2019-06-24T07:41:18 as input.
This should result in all rows from the db where the datetime coinsides with the beginning of the interval, which in my db is only the second row: 2019-06-24T07:41:13Z

However running the query, it seems to parse correctly:

from pygeofilter.parsers.cql_json import parse as parse_json
from pygeofilter.backends.sqlalchemy import to_filter
import sqlalchemy as sa

cql_json = "meets": [{ "property": "datetime" }, ["2019-06-24T07:41:13Z", "2019-06-24T07:41:18Z"]]

ast = parse_json(cql_json)
  TimeMeets(lhs=ATTRIBUTE datetime, rhs=Interval(start=datetime.datetime(2019, 6, 24, 7, 41, 13, tzinfo=<StaticTzInfo 'Z'>), end=datetime.datetime(2019, 6, 24, 7, 41, 18, tzinfo=<StaticTzInfo 'Z'>)))

but when it evaluates the ast to a SqlAlchemy expression, and queries the db, it returns both row 2 and 3: 2019-06-24T07:41:13Z and 2019-06-24T07:41:17Z

Inspecting the temporal method of filters.py in the sqlalchemy backend:
billede

it seems to handle special cases for before, after and tequals operations, thus other temporals end up being evaluated as either between, >=, or <= so my query ends up being evaluated as a between(datetime, "2019-06-24T07:41:13Z", "2019-06-24T07:41:18Z") explaining why row 3 is also returned

On a sidenote:
It seems that you have to specify an interval as input for anything besides before and after otherwise this crashes:
billede
with TypeError: cannot unpack non-iterable datetime.datetime object

From the OAF specification:

CQL supports date and timestamps as time instants, but even the smallest "instant" has a duration and can also be evaluated as an interval.

Hence to my understanding you should be able to run "meets", "metby", "begins" ect. on exact timedates, treating them as intervals, and not having to explicitly specify an interval (despite it being nonsensical to do in practise)

Am I completely missing something here or is the temporal method in fact not handling all temporal cases?

@Aramos93 Aramos93 changed the title SqlAlchemy temporal doesn't properly handle operations that aren't before, after or tequals SqlAlchemy temporal doesn't properly handle operations that aren't 'before', 'after' or 'tequals' Nov 5, 2021
@Aramos93 Aramos93 changed the title SqlAlchemy temporal doesn't properly handle operations that aren't 'before', 'after' or 'tequals' SqlAlchemy temporal operations not properly handled Nov 5, 2021
@constantinius
Copy link
Contributor

I'll investigate this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants