Как создать представление для таблицы с полями записи?

У нас есть еженедельный процесс резервного копирования, который экспортирует наше производственное хранилище Google Appengine Datastore в Google Cloud Storage, а затем в Google BigQuery. Каждую неделю мы создаем новый набор данных с именем как YYYY_MM_DD который содержит копию производственных таблиц в этот день. Со временем мы собрали много наборов данных, таких как 2014_05_10, 2014_05_17 и т. д. Я хочу создать набор данных Latest_Production_Data который содержит представление для каждой из таблиц в самой последней YYYY_MM_DD набор данных. Это облегчит для последующих отчетов один раз написать запрос и всегда получать самые последние данные.

Для этого у меня есть код, который получает самый последний набор данных и имена всех таблиц, которые набор данных содержит из API BigQuery. Затем для каждой из этих таблиц я запускаю вызов tables.insert, чтобы создать представление, которое является SELECT * из таблицы, которую я ищу, чтобы создать ссылку на.

Это не работает для таблиц, которые содержат RECORD поле, из того, что выглядит довольно милым правилом именования столбцов.

Например, у меня есть эта таблица:

Схема AccounDeletionRequest

Для которого я выпускаю этот вызов API:

{
  'tableReference': {
    'projectId': 'redacted',
    'tableId': u'AccountDeletionRequest',
    'datasetId': 'Latest_Production_Data'
  }
  'view': {
    'query': u'SELECT * FROM [2014_05_17.AccountDeletionRequest]'
  },
}

Это приводит к следующей ошибке:

HttpError: https://www.googleapis.com/bigquery/v2/projects//datasets/Latest_Production_Data/tables?alt=json вернул "Неверное имя поля"__key__. Namespace". Поля должны содержать только буквы, цифры и символы подчеркивания, начинаться с буквы или подчеркивания и содержать не более 128 символов.">

Когда я выполняю этот запрос в веб-консоли BigQuery, столбцы переименовываются для перевода . для _, Я ожидал, что то же самое произойдет, когда я выполню вызов API create view.

Выберите звездные результаты

Есть ли простой способ, которым я могу программно создать представление для каждой из таблиц в моем наборе данных, независимо от их базовой схемы? Проблема, с которой я сталкиваюсь сейчас, касается столбцов записей, но я ожидаю еще одну проблему для таблиц с повторяющимися полями. Есть ли волшебная альтернатива SELECT * что позаботится обо всех этих тонкостях для меня?

У меня была еще одна идея - сделать копию таблицы, но я бы предпочел не дублировать данные, если вообще смогу их избежать.

2 ответа

Решение

Вот обходной код, который я написал, чтобы динамически генерировать SELECT утверждение для каждой из таблиц:

def get_leaf_column_selectors(dataset, table):
    schema = table_service.get(
            projectId=BQ_PROJECT_ID,
            datasetId=dataset,
            tableId=table
        ).execute()['schema']

    return ",\n".join([
        _get_leaf_selectors("", top_field)
        for top_field in schema["fields"]
    ])


def _get_leaf_selectors(prefix, field):
    if prefix:
        format = prefix + ".%s"
    else:
        format = "%s"

    if 'fields' not in field:
        # Base case
        actual_name = format % field["name"]
        safe_name = actual_name.replace(".", "_")
        return "%s as %s" % (actual_name, safe_name)
    else:
        # Recursive case
        return ",\n".join([
            _get_leaf_selectors(format % field["name"], sub_field)
            for sub_field in field["fields"]
        ])

У нас была ошибка, из-за которой вам нужно было выбрать отдельные поля в представлении и использовать "как", чтобы переименовать поля во что-то допустимое (т. Е. У них нет "." В имени).

Ошибка исправлена, поэтому вы больше не должны видеть эту проблему. Пожалуйста, пропингуйте эту ветку или начните новый вопрос, если увидите его снова.

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