Как мне перевести сущность Datastore в объект BigQuery TableRow в Java?

У меня есть следующая функция DoFN, которая делает это, но нет документации по вопросам, которые я мог бы найти по этому поводу.

  • Проблема № 1 заключается в том, как автоматически преобразовать ключи, чтобы они создавались в BigQuery так же, как это делает BigQuery при импорте файла резервной копии формы Datastore?
  • Проблема № 2 заключается в том, как обрабатывать метки времени? Код ниже разрывает конвейер со следующим сообщением:

JSON-объект указан для поля без записи: отметка времени

Вот код, который я написал:

public class SensorObservationEntityToRowFn extends DoFn<Entity, TableRow> {
    /**
     * In this example, put the whole string into single BigQuery field.
     */
    @Override
    public void processElement(ProcessContext c) {
        Map<String, Value> props = getPropertyMap(c.element());
        TableRow row = new TableRow();
        row.set("id", c.element().getKey().getPathElement(c.element().getKey().getPathElementCount()-1).getId());
        if (
                props.get("property1") != null &&
                props.get("property2") != null
                ) {
            // Map data from the source Entity to the destination TableRow
            row.set("property1", props.get("property1").getStringValue());
            row.set("property2", props.get("property2").getStringValue());
        }
        row.set("source_type", props.get("source_type").getStringValue());
        DateTime dateTime = new DateTime(props.get("timestamp").getTimestampMicrosecondsValue()/1000L);
        row.set("timestamp", dateTime);
        // Output new TableRow only if all data is present in the source
        c.output(row);
    }
}

1 ответ

Я ожидал, что найду что-нибудь на уроках помощников, но у меня ничего не получилось. Думаю, Google все еще добавляет новые биты в свои API. Возможно в следующей версии. Самая большая проблема в том, что API немного не интуитивно понятен и не совместим с другими частями. Ключ сущности должен иметь свой собственный метод доступа вместо того, чтобы копать путь предка следующим образом (получить последний элемент массива пути):

getKey().getPathElement(c.element().getKey().getPathElementCount()-1).getId()

Вторая проблема с временными метками: тоже немного нелегко. Я нигде не смог найти в документации, как отформатировать метку времени в Datastore или в BigQuery с точки зрения API (тип данных, длина поля, его формат и т. Д.). Решение, которое работает сейчас, требует сторонней библиотеки ("joda"):

import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;

И приведенный ниже перевод данных. Вы должны помнить, что это в миллисекундах в одном месте и в микросекундах в другом. Еще одна ненужная путаница.

DateTime dateTime = new DateTime(props.get("timestamp").getTimestampMicrosecondsValu‌​e()/1000L);

row.set("timestamp", ISODateTimeFormat.dateTime().print(dateTime));

Надеюсь, это поможет другим, работающим с Dataflow и перемещающим данные из одного места в другое.

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