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

bug: data type inference in timestamp .delta expression #9387

Open
1 task done
martin-wiebusch-thg opened this issue Jun 14, 2024 · 0 comments
Open
1 task done

bug: data type inference in timestamp .delta expression #9387

martin-wiebusch-thg opened this issue Jun 14, 2024 · 0 comments
Labels
bug Incorrect behavior inside of ibis

Comments

@martin-wiebusch-thg
Copy link

martin-wiebusch-thg commented Jun 14, 2024

What happened?

I am trying to compute the difference between a timestamp literal and a timestamp column using the .delta method. The following code

import ibis
from ibis import _
import datetime as dt

con = ibis.bigquery.connect()
end_date = dt.datetime(2024, 6, 13, tzinfo=dt.timezone.utc)

table = (
    con.table('some_bigquery_table')
    .select(ts=_.some_timestamp_column)
    .mutate(dt=ibis.literal(end_date).delta(_.ts, 'second'))
)
print(con.compile(transactions))

raises InputTypeError: Unable to infer datatype of value _.ts with type <class 'ibis.common.deferred.Deferred'>

It works if I first create the literal as a column and then mutate it:

import ibis
from ibis import _
import datetime as dt

con = ibis.bigquery.connect()
end_date = dt.datetime(2024, 6, 13, tzinfo=dt.timezone.utc)

table = (
    con.table('some_bigquery_table')
    .select(
        ts=_.Order_Created,
        dt=ibis.literal(end_date),
    )
    .mutate(dt=_.dt.delta(_.ts, 'second'))
)
print(con.compile(transactions))

What version of ibis are you using?

9.0.0

What backend(s) are you using, if any?

BigQuery

Relevant log output

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/expr/operations/core.py:69, in Value.__coerce__(cls, value, T, S)
     68 try:
---> 69     dtype = dt.DataType.from_typehint(T)
     70 except TypeError:

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/expr/datatypes/core.py:173, in DataType.from_typehint(cls, typ, nullable)
    172 if issubclass(typ, Parametric):
--> 173     raise TypeError(
    174         f"Cannot construct a parametric {typ.__name__} datatype based "
    175         "on the type itself"
    176     )
    177 elif issubclass(typ, DataType):

TypeError: Cannot construct a parametric Timestamp datatype based on the type itself

During handling of the above exception, another exception occurred:

InputTypeError                            Traceback (most recent call last)
Cell In[15], line 17
      3     transactions = (
      4         con.table('the-hut-group.ditto_hqdw.Transactions')
      5         .select(ts=_.Order_Created)
   (...)
     11         # .mutate(dt=_.dt.delta(_.ts, 'second'))
     12     )
     13     print(con.compile(transactions))
---> 17 extract_events(con, con2)

Cell In[15], line 6, in extract_events(con, con2)
      1 def extract_events(con, con2):
      2     end_date = dt.datetime(2024, 6, 13, tzinfo=dt.timezone.utc)
      3     transactions = (
      4         con.table('the-hut-group.ditto_hqdw.Transactions')
      5         .select(ts=_.Order_Created)
----> 6         .mutate(dt=ibis.literal(end_date).delta(_.ts, 'second'))
      7         # .select(
      8         #     ts=_.Order_Created,
      9         #     dt=ibis.literal(end_date),
     10         # )
     11         # .mutate(dt=_.dt.delta(_.ts, 'second'))
     12     )
     13     print(con.compile(transactions))

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/expr/types/temporal.py:800, in TimestampValue.delta(self, other, part)
    729 def delta(
    730     self,
    731     other: datetime.datetime | Value[dt.Timestamp],
   (...)
    745     | Value[dt.String],
    746 ) -> ir.IntegerValue:
    747     """Compute the number of `part`s between two timestamps.
    748 
    749     ::: {.callout-note}
   (...)
    798     └──────────────┘
    799     """
--> 800     return ops.TimestampDelta(left=self, right=other, part=part).to_expr()

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/common/bases.py:72, in AbstractMeta.__call__(cls, *args, **kwargs)
     52 def __call__(cls, *args, **kwargs):
     53     """Create a new instance of the class.
     54 
     55     The subclass may override the `__create__` classmethod to change the
   (...)
     70 
     71     """
---> 72     return cls.__create__(*args, **kwargs)

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/common/grounds.py:119, in Annotable.__create__(cls, *args, **kwargs)
    116 @classmethod
    117 def __create__(cls, *args: Any, **kwargs: Any) -> Self:
    118     # construct the instance by passing only validated keyword arguments
--> 119     kwargs = cls.__signature__.validate(cls, args, kwargs)
    120     return super().__create__(**kwargs)

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/common/annotations.py:490, in Signature.validate(self, func, args, kwargs)
    487 param = self.parameters[name]
    488 pattern = param.annotation.pattern
--> 490 result = pattern.match(value, this)
    491 if result is NoMatch:
    492     errors.append((name, value, pattern))

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/common/patterns.py:865, in GenericCoercedTo.match(self, value, context)
    863 def match(self, value, context):
    864     try:
--> 865         value = self.origin.__coerce__(value, **self.params)
    866     except CoercionError:
    867         return NoMatch

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/expr/operations/core.py:71, in Value.__coerce__(cls, value, T, S)
     69         dtype = dt.DataType.from_typehint(T)
     70     except TypeError:
---> 71         dtype = dt.infer(value)
     73 try:
     74     return Literal(value, dtype=dtype)

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/common/dispatch.py:140, in lazy_singledispatch.<locals>.call(arg, *args, **kwargs)
    137 @functools.wraps(func)
    138 def call(arg, *args, **kwargs):
    139     impl = dispatcher.dispatch(type(arg))
--> 140     return impl(arg, *args, **kwargs)

File ~/.pyenv/versions/3.10.6/envs/general/lib/python3.10/site-packages/ibis/expr/datatypes/value.py:35, in infer(value)
     32 @lazy_singledispatch
     33 def infer(value: Any) -> dt.DataType:
     34     """Infer the corresponding ibis dtype for a python object."""
---> 35     raise InputTypeError(
     36         f"Unable to infer datatype of value {value!r} with type {type(value)}"
     37     )

InputTypeError: Unable to infer datatype of value _.ts with type <class 'ibis.common.deferred.Deferred'>

Code of Conduct

  • I agree to follow this project's Code of Conduct
@martin-wiebusch-thg martin-wiebusch-thg added the bug Incorrect behavior inside of ibis label Jun 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Incorrect behavior inside of ibis
Projects
Status: backlog
Development

No branches or pull requests

1 participant