Opened 4 weeks ago
Closed 4 weeks ago
#37323 closed Bug (duplicate)
Reading a DateField from a column of type timestamp produces python datetime.datetime
| Reported by: | uli123abc | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | |
| Severity: | Normal | Keywords: | DateField, timestamp, date, datetime |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Current behavior:
According to documented behavior [1], DateField should represent a datetime.date object. If however the database column (Postgresql) is of type timestamp [2], reading the field will produce a datetime.datetime object.
Expected behavior:
The ORM should warn about a type mismatch or cast the database value to a datetime.date object.
[1] https://docs.djangoproject.com/en/6.1/ref/models/fields/#datefield
[2] https://www.postgresql.org/docs/current/datatype-datetime.html
Change History (3)
follow-up: 2 comment:1 by , 4 weeks ago
comment:2 by , 4 weeks ago
Replying to Yassin Bahri:
Detecting this on every read would also require additional schema introspection.
I don't see why, because isinstance(read_value, datetime.datetime) in Python is sufficient to detect it.
The mismatch wasn't intentional in that case and relying on DateField to produce datetime.date introduced a bug in the code that relied on that.
Overall the behavior seems to be consistent though with other field types such as IntegerField when used on a float column type.
The schema should normally be corrected to use
date
I agree that altering the column type in the database is overall the best solution.
comment:3 by , 4 weeks ago
| Resolution: | → duplicate |
|---|---|
| Status: | new → closed |
Duplicate of #23803.
While the database is different (sqlite -> postgres) the underlying issue and potential solutions in user projects are the same.
I reproduced this against PostgreSQL 17.4 using Django 4.2.26, 5.2.8, 6.0, and 6.1.
In each version, a model declaring:
returns a
datetime.datewhile the corresponding database column is a PostgreSQLdate. After manually altering that column totimestamp, PostgreSQL/psycopg returns adatetime.datetimeinstead.This does not appear to be a regression. The model definition and physical database schema disagree:
DateFieldcreates and expects adatecolumn, while the actual column is atimestamp. Automatically converting the returned value would hide the schema mismatch and could silently discard the time component. Detecting this on every read would also require additional schema introspection.The schema should normally be corrected to use
date, or the model should useDateTimeFieldto match the existingtimestampcolumn.If the mismatch is intentional, an explicit database cast works:
I verified that
happened_on_as_dateis then adatetime.date. This is also consistent with #31506, which clarified that declaring an output field does not itself perform a database cast.I think this ticket can be closed as
invalid.