question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Can't set timezone-naive datetimes

See original GitHub issue

Describe the bug Can’t set timezone-naive datetimes

To Reproduce

  1. Model with two DatetimeFields and type sqlalchemy.DateTime(timezone=False)
  2. Save timezone-naive datetime to first field (All ok)
  3. Save timezone-naive datetime to second field (Error, can’t compare aware and naive dts)

values from backends/base/executor.py:execute_update:

  • from first execute: [datetime.datetime(2021, 2, 2, 0, 0), None]
  • from second: [datetime.datetime(2021, 2, 2, 0, 0, tzinfo=<UTC>), datetime.datetime(2021, 3, 17, 14, 38, 11)]

So, as we can see, on second execute, first field value have UTC timezone

Expected behavior Timezone-naive fields

Additional context PostgreSQL : latest Tortoise-orm : latest Alembic with SQLAlchemy (for migrations) : latest

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:10

github_iconTop GitHub Comments

3reactions
rafalstapinskicommented, Mar 18, 2021

Having the same issue,

tl;dr is that the column schema in postgres is timezone without time zone but tortoise’s auto create and auto update timestamp functions are always datetime aware

The docs in tortoise orm state

When set use_tz = True, tortoise will always store UTC time in database no matter what timezone set

and tortoise achieves this with setting its “now” on auto create and auto update timestamps to be

def now() -> datetime:
    """
    Return an aware datetime.datetime, depending on use_tz and timezone.
    """
    if get_use_tz():
        return datetime.now(tz=pytz.utc)
    else:
        return datetime.now(get_default_timezone())

As you can see, both of these create timezone-aware datetimes. Because these are timezone aware (despite being UTC), they can not be compared to the database timezone-naive (timestamp without time zone in psql) at the adapter (asyncpg) level.

My practice (and generally as well, to my knowledge) is to store UTC timestamps in postgres but keep them timezone naive. Tortoise’s implementation has changed to keep all postgres columns TIMESTAMPTZ or timestamp with time zone which clashes with the underlying column.

One option here is to change all your created and updated columns in your database to be timezone aware at UTC.

Personally, I’m going to run a fork of this going forward with the change that all my timezone columns will have the SQL_TYPE of timestamp without time zone and will strictly use datetime.utcnow()… like the description says in the first place…


class DatetimeField(Field, datetime.datetime):
    """
    Datetime field.

    ``auto_now`` and ``auto_now_add`` is exclusive.
    You can opt to set neither or only ONE of them.

    ``auto_now`` (bool):
        Always set to ``datetime.utcnow()`` on save.
    ``auto_now_add`` (bool):
        Set to ``datetime.utcnow()`` on first save only.
    """

What I hope tortoise-orm adopts, however, is for USE_TZ to actually do what its name implies in that

  • use_tz will tell you whether your datetimes are timezone aware
  • if true
    • use the timezone specified by passing in timezone
  • if false
    • create datetime columns without a time zone (e.g. timestamp without time zone for postgres)
    • have the tortoise.timestamp.now() function return `datetime.utcnow(), a timezone naive datetime
0reactions
Achilles0509commented, Mar 22, 2022

Faced the same issue. I tried with use_tz=True and use_tz=False options, both are failed.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to make a timezone aware datetime object
In general, to make a naive datetime timezone-aware, use the localize method: import datetime import pytz unaware = datetime.datetime(2011, ...
Read more >
Working with Datetime Objects and Timezones in Python
A naive datetime object contains no timezone information. The easiest way to tell if a datetime object is naive is by checking tzinfo....
Read more >
How to make a timezone aware datetime object in Python
We can easily check if a datetime object is timezone-aware or not. For this, we will store the current date and time in...
Read more >
Why naïve times are local times in Python
The reason for this is simple: it's possible to change your system local time zone during the run of a Python program, and...
Read more >
Working With TimeZones in Python
Create Timezone Aware Datetime Object · Install pytz module if not installed using the pip install pytz command. · Use the pytz.timezone(' ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found