Как мне перевести сущность 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").getTimestampMicrosecondsValue()/1000L);
row.set("timestamp", ISODateTimeFormat.dateTime().print(dateTime));
Надеюсь, это поможет другим, работающим с Dataflow и перемещающим данные из одного места в другое.