Тип данных не меняется в MongoDB через блоки данных Pyspark (от строки до даты)

Я пытаюсь загрузить несколько документов в коллекцию MongoDb, используя блоки данных pyspark, и во время загрузки я также использую файл updateDate, но после загрузки я увидел, что тип данных поля updateDate — это строка, а не тип данных даты.

здесь я использую код для отметки времени.

import datetime

current_timestamp_utc = datetime.datetime.now(datetime.timezone.utc)
formatted_timestamp = current_timestamp_utc.strftime("%Y-%m-%dT%H:%M:%S")
timezone_offset = current_timestamp_utc.strftime("%z")
formatted_timestamp = formatted_timestamp + ".000" + timezone_offset[:-2] + ":" + 
timezone_offset[-2:]

print(formatted_timestamp)

result : 2024-04-03T07:33:52.000+00:00

результат выглядит нормально, но после загрузки в MongoDb он отображается как строка вместо даты.

Не могли бы вы помочь мне, как загрузить документы с типом данных даты? Я использовал метод UpdateMany() для изменения типа данных string на дату, и является ли это подходом к записи, чтобы продолжить, или есть ли какое-либо влияние на ввод-вывод или производительность при использовании метода updatemany(). Пожалуйста, предложите

Вы используете strftime(), так почему вы ожидаете Date в результате, вы составляете строку. А почему вы используете + timezone_offset[:-2] + ":" + timezone_offset[-2:] вместо простого strftime("%Y-%m-%dT%H:%M:%S%z")? + ".000" тоже бессмысленно.

Wernfried Domscheit 04.04.2024 07:23

Если вы хотите вставить значение Date, просто попробуйте вставить datetime.datetime.now(datetime.timezone.utc) напрямую. Само значение Date не имеет никакого формата.

Wernfried Domscheit 04.04.2024 07:27

Спасибо за предоставление подробной информации, но я хотел бы сохранить в этом формате 2024-04-03T07:33:52.000+00:00 в MongoDB согласно требованию и когда я пытался использовать datetime.datetime.now(datetime.timezone .utc), получив 2024-04-04 10:26:58.241295+00:00 <класс 'datetime.datetime'>.

Phani Kumar 04.04.2024 12:34

Нет, опять же, у Date нет никакого формата (или, по крайней мере, у него есть формат, о котором вам вообще не следует беспокоиться). Вы имеете в виду то, как дата отображается на вашем клиенте, но это не имеет никакого отношения к тому, как значение хранится внутри вашей базы данных.

Wernfried Domscheit 04.04.2024 14:26

Я вообще не знаю искру. Возможно, вы не можете использовать его напрямую, тогда вам нужно будет преобразовать дату в строку (видимо, именно это вы и сделали), а затем преобразовать строку в BSON-Date. Взгляните на $dateFromString

Wernfried Domscheit 04.04.2024 14:31
Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
1
5
101
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы можете получить текущее время напрямую, используя функции даты и времени Spark SQL следующим образом:

from pyspark.sql import SparkSession
from pyspark.sql.functions import date_format, current_timestamp

spark = SparkSession.builder.getOrCreate()

spark.sql("""select date_format(current_timestamp(), "yyyy-MM-dd'T'HH:MM:ss.SSSxxx") as updateDate""").show(truncate=False)

Output:
+-----------------------------+
|updateDate                   |
+-----------------------------+
|2024-04-04T09:04:35.865+00:00|
+-----------------------------+

Schema:
root
 |-- updateDate: string (nullable = false)

Если вы заметили схему, updateDate — это строка, и вы можете преобразовать ее в метку времени, используя to_timestamp(), следующим образом:

from pyspark.sql import SparkSession
from pyspark.sql.functions import date_format, current_timestamp, to_timestamp

spark = SparkSession.builder.getOrCreate()

spark.sql("""select to_timestamp(date_format(current_timestamp(), "yyyy-MM-dd'T'HH:MM:ss.SSSxxx")) as updateDate""").show(truncate=False)

Output:
+-----------------------+
|updateDate             |
+-----------------------+
|2024-04-04 09:04:12.703|
+-----------------------+

Schema:
root
 |-- updateDate: timestamp (nullable = true)

И теперь updateDate — это временная метка, скорректированная для часового пояса вашего сеанса Spark (именно поэтому смещение +00:00 теперь исчезло), которое, кстати, вы можете обновить с помощью spark.conf.set("spark.sql.session.timeZone", "<enter-timezone-here>").

И если вы хотите добавить его в существующий фрейм данных в качестве нового столбца, вы можете сделать что-то вроде этого:

from pyspark.sql import SparkSession
from pyspark.sql.functions import date_format, current_timestamp

spark = SparkSession.builder.getOrCreate()

df = spark.createDataFrame([(1,), (2,)], ["rownum"]) # replace this with your dataframe

df = df.withColumn("updateDate", date_format(current_timestamp(), "yyyy-MM-dd'T'HH:MM:ss.SSSxxx").cast("timestamp"))

df.show(truncate=False)
df.printSchema()

Output:
+------+-----------------------+
|rownum|updateDate             |
+------+-----------------------+
|1     |2024-04-04 09:04:48.473|
|2     |2024-04-04 09:04:48.473|
+------+-----------------------+

Schema:
root
 |-- rownum: long (nullable = true)
 |-- updateDate: timestamp (nullable = true)

Тип данных, который вы ищете, — это временная метка с часовым поясом в Spark. Теперь вы можете попробовать загрузить набор данных в MongoDB с помощью этой схемы.

Я попробовал следующий подход в Pyspark:

DataFrame.printSchema DataFrame [id: int, дата: строка]

df1 = Dilip_df.withColumn("date", to_date("date", "yyyy/MM/dd HH:mm:ss"))

Полученные результаты:

+---+----------+
| id|      date|
+---+----------+
|  1|2022-01-01|
|  2|2022-01-02|
|  3|2022-01-03|
+---+----------+

root
 |-- id: integer (nullable = true)
 |-- date: date (nullable = true)

В приведенном выше коде я использовал функцию withColumn() для создания нового столбца с именем «дата» и использовал функцию to_date() для преобразования столбца «дата» в DateType. Строка формата «гггг/ММ/дд ЧЧ:мм:сс» определяет формат входной строки даты.

Однако, как вы упомянули, вы загружаете файлы в MangoDB. Согласно $toDate (агрегация)

$toDate Преобразует значение в дату. Если значение невозможно преобразовать в дату, $toDate ошибки. Если значение равно нулю или отсутствует, $toDate возвращает ноль.

Вы также можете попробовать следующее в MangoDB версии 4.2:

from datetime import datetime
mydate = datetime.strptime(‘08/12/1977 09:45:34 AM’, ‘%d/%m/%Y %I:%M:%S %p’)
mydate = mydate.isoformat()

Ссылка: Преобразование типа данных String Datatype в Date$convert (агрегация)

Другие вопросы по теме