tortoise / tortoise-orm

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

fix: `DatetimeField` use __year report `'int' object has no attribute 'utcoffset'` #1580

Closed waketzheng closed 2 months ago

waketzheng commented 2 months ago

Fix DatetimeField use '__year' report 'int' object has no attribute 'utcoffset'. (#1575) When config with "use_tz": True, the bug can be reproduced.

abondar commented 2 months ago

Hello!

Please rebase on actual develop branch and add corresponding test, that will show that problem is gone

waketzheng commented 2 months ago

The bug can be reproduce by:

from datetime import datetime

from tortoise import Tortoise, fields, run_async
from tortoise.models import Model

class Event(Model):
    id = fields.IntField(pk=True)
    name = fields.TextField()
    created = fields.DatetimeField(null=True)

    class Meta:
        table = "event"

    def __str__(self):
        return self.name

async def run():
    # url = 'mysql://root:123456@127.0.0.1:3306/test_year'
    url = "asyncpg://postgres:postgres@127.0.0.1:5432/test_year"
    await Tortoise.init(db_url=url, modules={"models": ["__main__"]}, use_tz=True)
    await Tortoise.generate_schemas()

    event = await Event.create(name="Test", created=datetime.now())
    print(event.created)

    events = await Event.filter(created__year=2024)
    print(events)

if __name__ == "__main__":
    run_async(run())
coveralls commented 2 months ago

Pull Request Test Coverage Report for Build 8856620005

Details


Totals Coverage Status
Change from base Build 8850757408: 0.03%
Covered Lines: 5735
Relevant Lines: 6388

💛 - Coveralls
abondar commented 2 months ago

Please add such testcase

async def test_filter_by_year(self):
        with patch.dict(os.environ, {"USE_TZ": "True"}):
            obj = await testmodels.DatetimeFields.create(datetime=datetime(year=2024, month=1, day=1))
            filtered_obj = await testmodels.DatetimeFields.filter(datetime__year=2024).first()
            assert obj == filtered_obj

to tests.fields.test_time.TestDatetimeFields

abondar commented 2 months ago

Seems like mssql doesn't support extract syntax, and uses some kind of CONVERT() syntax instead I think fixing it is out of scope for this PR, so you could just exclude mssql from this testcase

waketzheng commented 2 months ago

@abondar done.