Я пытаюсь загрузить несколько документов в коллекцию 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(). Пожалуйста, предложите
Если вы хотите вставить значение Date
, просто попробуйте вставить datetime.datetime.now(datetime.timezone.utc)
напрямую. Само значение Date
не имеет никакого формата.
Спасибо за предоставление подробной информации, но я хотел бы сохранить в этом формате 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'>.
Нет, опять же, у Date
нет никакого формата (или, по крайней мере, у него есть формат, о котором вам вообще не следует беспокоиться). Вы имеете в виду то, как дата отображается на вашем клиенте, но это не имеет никакого отношения к тому, как значение хранится внутри вашей базы данных.
Я вообще не знаю искру. Возможно, вы не можете использовать его напрямую, тогда вам нужно будет преобразовать дату в строку (видимо, именно это вы и сделали), а затем преобразовать строку в BSON-Date. Взгляните на $dateFromString
Вы можете получить текущее время напрямую, используя функции даты и времени 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 (агрегация)
Вы используете
strftime()
, так почему вы ожидаетеDate
в результате, вы составляете строку. А почему вы используете+ timezone_offset[:-2] + ":" + timezone_offset[-2:]
вместо простогоstrftime("%Y-%m-%dT%H:%M:%S%z")
?+ ".000"
тоже бессмысленно.