edgedb-python icon indicating copy to clipboard operation
edgedb-python copied to clipboard

Passing datetime args to a function requires unreasonable type wrangling

Open anbuzin opened this issue 5 months ago • 1 comments

Schema:

module default {
    type Chat {
        content: str;
    }

    function insert_summary(chat_id: uuid, some_date: datetime) -> Chat 
    using (
        with
            chat := (select Chat filter .id = chat_id)
        select assert_exists(chat)
    );
}

Python:

from models import default, std
import gel
import asyncio
import uuid
import datetime


client = gel.create_async_client()


async def main():
    q = default.insert_summary(
        chat_id=std.uuid(uuid.UUID("628612c0-4cf6-11f0-bb23-c7e1e2da40cb")),
        some_date=std.datetime(
            datetime.datetime(2025, 6, 19, 11, 5, 17).replace(
                tzinfo=datetime.timezone.utc
            )
        ),
    )
    result = await client.query(q)


if __name__ == "__main__":
    asyncio.run(main())

This is the minimum possible variant that the QB agreed to work with, and I got a spasm in my scapula while trying to work it out in the context of a FastAPI app that's doing automagic parsing/casting.

The kinds of errors I've encountered:

# no timezone info
gel.errors.InvalidValueError: invalid input syntax for type std::datetime: '2025-06-19 11:05:17'
class SummarizeRequest(BaseModel):
    cutoff: datetime

# ...

cutoff = std.datetime(request.cutoff)
# TypeError: str cannot be converted to an Expr
# when passing raw Python datetime as an arg
TypeError: datetime.datetime cannot be converted to an Expr

UUIDs are no better, but at least they are easier to get right. Could we please make the errors more descriptive?

anbuzin avatar Jun 19 '25 11:06 anbuzin