edgedb-python
edgedb-python copied to clipboard
Passing datetime args to a function requires unreasonable type wrangling
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?
Honestly at this point I don't know what I'm doing wrong.
assert isinstance(request.chat_id, uuid.UUID)
assert isinstance(request.cutoff, datetime.datetime)
chat_id = std.uuid(request.chat_id)
cutoff = std.datetime(request.cutoff.replace(microsecond=0, tzinfo=datetime.timezone.utc))
# when passed as args
# TypeError: str cannot be converted to an Expr
Same error for this:
chat_id = std.uuid_generate_v4()
cutoff = std.datetime_current()