tortoise / tortoise-orm

Familiar asyncio ORM for python, built with relations in mind
https://tortoise.github.io
Apache License 2.0
4.7k stars 391 forks source link

Timezone-aware datetime returns incorrect timezone for SQLite #1742

Closed seriaati closed 1 month ago

seriaati commented 1 month ago

Describe the bug When I create a new object in a SQLite database, the timezone being put into the database, and the timezone being retrieved from the database, are different from the value I originally inputted.

To Reproduce

import datetime
from tortoise import Tortoise, Model, fields, run_async

class TestModel(Model):
    dt = fields.DatetimeField()

async def main() -> None:
    await Tortoise.init(db_url="sqlite://:memory:", modules={"models": ["__main__"]}, use_tz=True)
    await Tortoise.generate_schemas()

    now = datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=1)))
    print(now.tzinfo)
    test = await TestModel.create(dt=now)
    print(test.dt.tzinfo)

run_async(main())

Result:

UTC+01:00
UTC

Expected behavior Expected result:

UTC+01:00
UTC+01:00
henadzit commented 1 month ago

Looks like it is not just a sqlite issue. The aware datetime value is updated to be local explicitly when the record is loaded from the database https://github.com/tortoise/tortoise-orm/blob/0ddf8d327949be3ad812c41e4215c85b997214b9/tortoise/fields/data.py#L357

Django preserves the timezone value though. I'll look into it more later.

henadzit commented 1 month ago

@seriaati actually Django converts a datetime to UTC on save too, see https://docs.djangoproject.com/en/5.1/topics/i18n/timezones/#overview

Tortoise mentions that the design of timezone is inspired by Django here but looks like the tortoise documentation is a bit misleading. It states that "When set use_tz = True, tortoise will always store UTC time in database no matter what timezone set" but it looks like it does so even if use_tz = False and timezone is not set.

seriaati commented 1 month ago

I see, thanks for the answer! So then, what impact does use_tz have on the storing of datetime data?