#python #django #postgresql #datetime #psycopg2
Вопрос:
Я пытаюсь извлечь datetime
типизированные данные из postgresql на django.
Но если микросекунда имеет начальное значение 0, как показано ниже
| datetime_field |
|2021-06-07 09:22:13.099866 00 |
результат показан в виде
datetime.datetime(2021, 6, 7, 9, 22, 13, 998660, tzinfo=<UTC>)
на языке Python.
Обратите внимание на микросекунду 099866. Он был изменен на 998660.
Если я вставлю полученный объект datetime без каких-либо изменений в postgresql, он будет загружен, как показано ниже.
| datetime_field |
| 2021-06-07 09:22:13.99866 00 |
0 в начале исчезло.
Похоже, эта проблема связана с psycopg2, а не только с django, но я не могу найти никакого решения для этого.
Как я могу получить микросекунды во всей их полноте?
p.s. Добро пожаловать для редактирования только на английском языке. Поскольку я не говорю по-английски, я не уверен, правильно ли я написал выражения.
Добавление точного шага.
Я выполняю работу над контейнерами docker. Сейчас используются два контейнера, каждый для сервера django и сервера PostgreSQL.
Version infos:
Python 3.9.1
Django==3.1.4
psycopg2==2.8.6
postgres (PostgreSQL) 13.1 (Debian 13.1-1.pgdg100 1)
Я тестирую с помощью клона производственной базы данных.
- ВЫБЕРИТЕ запрос для проблемных данных.
TEST=# SELECT issued_at FROM table_name WHERE id = 153;
issued_at
-------------------------------
2021-06-18 10:10:49.075392 00
(1 row)
- В
python manage.py shell
, извлеките данные с помощьюconnections.cursor()
>>> with transaction.atomic():
... query = f'''SELECT issued_at FROM table_name WHERE id = 153;'''
... with connections['test_db'].cursor() as cursor:
... cursor.execute(query)
... print(cursor.fetchone())
...
(datetime.datetime(2021, 6, 18, 10, 10, 49, 753920, tzinfo=<UTC>),)
Дополнение 2.
Когда я получаю данные с помощью django Model.objects.get()
, результат получается хорошим.
>>> data = TableName.objects.get(id=153)
>>> data.issued_at
datetime.datetime(2021, 6, 18, 10, 10, 49, 75392, tzinfo=<UTC>)
Это кажется своего рода проблемой django.db.connections
.
Комментарии:
1. Это похоже на потенциальную ошибку. Возможно, вы можете создать билет для этого: code.djangoproject.com/newticket
2. значения отправляются в базу данных в виде чисел, а не в виде строк. вы можете сохранить их в виде строки, а затем вставить.
3. @NikhilB: да, но дело в том, что чтение и запись должны быть обратными друг другу: если вы записываете некоторую метку времени в базу данных, вы ожидаете, что прочитаете то же значение обратно. Здесь это не так, что довольно странно .
4. @WillemVanOnsem Спасибо тебе. Я создам его, если окажется, что это ошибка. Сейчас я еще немного его тестирую.
5. Это был глупый вопрос. Я допустил ошибку при извлечении данных. Извините всех и спасибо за вашу любезную помощь.
Ответ №1:
Я этого не вижу:
CREATE TABLE public.dt_test (
id integer,
ts_fld timestamp without time zone,
tsz_fld timestamp with time zone
);
insert into dt_test values (1, '2021-06-07 09:22:13.099866 00', '2021-06-07 09:22:13.099866 00');
insert into dt_test values (2, '2021-06-07 09:22:13.99866 00', '2021-06-07 09:22:13.99866 00');
select * from dt_test ;
id | ts_fld | tsz_fld
---- ---------------------------- -------------------------------
1 | 2021-06-07 09:22:13.099866 | 2021-06-07 02:22:13.099866-07
2 | 2021-06-07 09:22:13.99866 | 2021-06-07 02:22:13.99866-07
import psycopg2
cur.execute('select * from dt_test')
rs = cur.fetchall()
rs
Out[23]:
[(1,
datetime.datetime(2021, 6, 7, 9, 22, 13, 99866),
datetime.datetime(2021, 6, 7, 2, 22, 13, 99866, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=-420, name=None))),
(2,
datetime.datetime(2021, 6, 7, 9, 22, 13, 998660),
datetime.datetime(2021, 6, 7, 2, 22, 13, 998660, tzinfo=psycopg2.tz.FixedOffsetTimezone(offset=-420, name=None)))]
cur.execute('insert into dt_test(id, ts_fld) values(%s, %s)', [3, datetime.datetime(2021, 6, 7, 9, 22, 13, 99866)])
con.commit()
select * from dt_test ;
id | ts_fld | tsz_fld
---- ---------------------------- -------------------------------
1 | 2021-06-07 09:22:13.099866 | 2021-06-07 02:22:13.099866-07
2 | 2021-06-07 09:22:13.99866 | 2021-06-07 02:22:13.99866-07
3 | 2021-06-07 09:22:13.099866 | NULL
То, что вы видите, — это нормализация до 1000000:
select 998660/1000000.0;
?column?
------------------------
0.99866000000000000000
select 99866/1000000.0;
?column?
------------------------
0.09986600000000000000
Комментарии:
1. Вау… извини, что я неправильно понял это. Спасибо, я попробую еще раз.
2. Хм, кажется, с моим тестом все немного по-другому. Могу я получить информацию о вашей версии? Я тестирую на postgres v13.1.
postgres (PostgreSQL) 13.1 (Debian 13.1-1.pgdg100 1)
,Django==3.1.4
иpsycopg2==2.8.6
.3. Я пробовал с
psycopg2 2.8.5 and 2.91
и.postgres 12.7 and 13.0
Я получаю те же результаты. Добавьте в свой вопрос точные шаги, которые вы предпринимаете в своем тесте, и возвращаемые результаты. На данный момент я бы оставилDjango
это в стороне . Также добавьтеPython
версию, которую вы используете.4. Это
Python 3.9.1
. Я изменил вопрос. Похожеdjango.db.connections
, с объектом что-то не так.5. Я нахожу, что в это трудно поверить, так как основной драйвер один и тот же, и это та часть, которая выполняет преобразование типов. Вы уверены
connections['test_db']
, что на самом деле указываете на то, что вы думаете?