Экспорт данных BigQuery в CSV без использования облачного хранилища Google

В настоящее время я пишу программное обеспечение, чтобы экспортировать большие объемы данных BigQuery и хранить полученные запросы локально в виде файлов CSV. Я использовал Python 3 и клиент, предоставленный Google. Я сделал настройку и аутентификацию, но проблема в том, что я не могу хранить данные локально. Каждый раз, когда я выполняю, я получаю следующее сообщение :

googleapiclient.errors.HttpError: https://www.googleapis.com/bigquery/v2/projects/round-office-769/jobs?alt=json возвращается "Неверный код URI получателя извлечения" /имя файла- *.csv '. Должен быть допустимый путь хранилища Google." >

Это моя конфигурация работы:

def export_table(service, cloud_storage_path,
             projectId, datasetId, tableId, sqlQuery,
             export_format="CSV",
             num_retries=5):

# Generate a unique job_id so retries
# don't accidentally duplicate export
job_data = {
    'jobReference': {
        'projectId': projectId,
        'jobId': str(uuid.uuid4())
    },
    'configuration': {
        'extract': {
            'sourceTable': {
                'projectId': projectId,
                'datasetId': datasetId,
                'tableId': tableId,
            },
            'destinationUris': ['response/file-name-*.csv'],
            'destinationFormat': export_format
        },
        'query': {
            'query': sqlQuery,
        }
    }
}
return service.jobs().insert(
    projectId=projectId,
    body=job_data).execute(num_retries=num_retries)

Я надеялся, что могу просто использовать локальный путь вместо облачного хранилища, чтобы хранить данные, но я ошибся.

Итак, мой вопрос:

Могу ли я загрузить запрошенные данные локально (или в локальную базу данных) или мне нужно использовать Google Cloud Storage?

Ответ 1

Для работы с экспортом необходимо использовать Google Cloud Storage. Экспорт данных из BigQuery объясняется здесь, проверьте также варианты для разных синтаксисов пути.

Затем вы можете загрузить файлы из GCS в локальное хранилище.

Gsutil инструмент поможет вам загрузить файл с GCS на локальный компьютер.

Вы не можете загружать с одним перемещением локально, сначала вам нужно экспортировать в GCS, а не на локальный компьютер.

Ответ 2

Вы можете загружать все данные напрямую (без маршрутизации через Google Cloud Storage), используя механизм подкачки. В основном вам нужно создать токен страницы для каждой страницы, загрузить данные на странице и повторить ее до тех пор, пока не будут загружены все данные, т.е. Больше нет токенов. Вот пример кода на Java, который, надеюсь, прояснит идею:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.bigquery.Bigquery;
import com.google.api.services.bigquery.BigqueryScopes;
import com.google.api.client.util.Data;
import com.google.api.services.bigquery.model.*;

/* your class starts here */

private String projectId = ""; /* fill in the project id here */
private String query = ""; /* enter your query here */
private Bigquery bigQuery;
private Job insert;
private TableDataList tableDataList;
private Iterator<TableRow> rowsIterator;
private List<TableRow> rows;
private long maxResults = 100000L; /* max number of rows in a page */

/* run query */
public void open() throws Exception {
    HttpTransport transport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = new JacksonFactory();
    GoogleCredential credential = GoogleCredential.getApplicationDefault(transport, jsonFactory);
    if (credential.createScopedRequired())
        credential = credential.createScoped(BigqueryScopes.all());
    bigQuery = new Bigquery.Builder(transport, jsonFactory, credential).setApplicationName("my app").build();

    JobConfigurationQuery queryConfig = new JobConfigurationQuery().setQuery(query);
    JobConfiguration jobConfig = new JobConfiguration().setQuery(queryConfig);
    Job job = new Job().setConfiguration(jobConfig);
    insert = bigQuery.jobs().insert(projectId, job).execute();
    JobReference jobReference = insert.getJobReference();

    while (true) {
        Job poll = bigQuery.jobs().get(projectId, jobReference.getJobId()).execute();
        String state = poll.getStatus().getState();
        if ("DONE".equals(state)) {
            ErrorProto errorResult = poll.getStatus().getErrorResult();
            if (errorResult != null)
                throw new Exception("Error running job: " + poll.getStatus().getErrors().get(0));
            break;
        }
        Thread.sleep(10000);
    }

    tableDataList = getPage();
    rows = tableDataList.getRows();
    rowsIterator = rows != null ? rows.iterator() : null;
}

/* read data row by row */
public /* your data object here */ read() throws Exception {
    if (rowsIterator == null) return null;

    if (!rowsIterator.hasNext()) {
        String pageToken = tableDataList.getPageToken();
        if (pageToken == null) return null;
        tableDataList = getPage(pageToken);
        rows = tableDataList.getRows();
        if (rows == null) return null;
        rowsIterator = rows.iterator();
    }

    TableRow row = rowsIterator.next();
    for (TableCell cell : row.getF()) {
        Object value = cell.getV();
        /* extract the data here */
    }

    /* return the data */
}

private TableDataList getPage() throws IOException {
    return getPage(null);
}

private TableDataList getPage(String pageToken) throws IOException {
    TableReference sourceTable = insert
            .getConfiguration()
            .getQuery()
            .getDestinationTable();
    if (sourceTable == null)
        throw new IllegalArgumentException("Source table not available. Please check the query syntax.");
    return bigQuery.tabledata()
            .list(projectId, sourceTable.getDatasetId(), sourceTable.getTableId())
            .setPageToken(pageToken)
            .setMaxResults(maxResults)
            .execute();
}

Ответ 3

Вы можете запустить tabledata.list() в этой таблице и установить "alt= csv", который вернет начало таблицы как CSV.

Ответ 4

Другой способ сделать это - из пользовательского интерфейса, как только результаты запроса вернутся, вы можете выбрать кнопку "Загрузить как CSV". введите описание изображения здесь

Ответ 5

Если вы устанавливаете API Google BigQuery и pandas и pandas.io, вы можете запускать Python внутри ноутбука Jupyter, запрашивать таблицу BQ и получать данные в локальный фрейм. Оттуда вы можете записать его в CSV.

Ответ 6

Как сказал Михаил Берлянт,

BigQuery не предоставляет возможность прямого экспорта/загрузки запроса результат в GCS или локальный файл.

Вы по-прежнему можете экспортировать его с помощью веб-интерфейса всего за три шага

  1. Сконфигурируйте запрос, чтобы сохранить результаты в таблице BigQuery и запустить его.
  2. Экспортируйте таблицу в корзину в GCS.
  3. Загрузите из ведра.

Чтобы расходы оставались низкими, просто удалите таблицу после экспорта содержимого в GCS и удалите содержимое из корзины и корзины после загрузки файлов на компьютер.

Шаг 1

Находясь на экране BigQuery, перед запуском запроса перейдите в "Дополнительно"> "Настройки запроса"

Configure Query

Это открывает следующее

Query Settings

Здесь вы хотите иметь

  • Назначение: установить таблицу назначения для результатов запроса
  • Название проекта: выберите проект.
  • Имя набора данных: выберите набор данных. Если у вас его нет, создайте его и возвращайтесь.
  • Имя таблицы: дайте любое имя, которое вы хотите (должно содержать только буквы, цифры или подчеркивания).
  • Размер результата: разрешить большие результаты (без ограничения размера).

Затем сохраните его, и запрос будет настроен для сохранения в определенной таблице. Теперь вы можете запустить запрос.

Шаг 2

Чтобы экспортировать его в GCP, вам нужно перейти к таблице и нажать EXPORT> Export to GCS.

BigQuery export table

Откроется следующий экран

Export to GCS

В Выберите местоположение GCS вы определяете область, папку и файл.

Например, у вас есть корзина с именем daria_bucket (используйте только строчные буквы, цифры, дефисы (-) и подчеркивания (_). Точки (.) Можно использовать для формирования правильного доменного имени.) И вы хотите сохранить файл ( s) в корне корзины с именем test вы пишете (в Select GCS location)

daria_bucket/test.csv

Если файл слишком большой (более 1 ГБ), вы получите сообщение об ошибке. Чтобы исправить это, вам нужно сохранить его в большем количестве файлов, используя подстановочный знак. Итак, вам нужно добавить *, просто так

daria_bucket/test*.csv

Wildcard export to GCS

Это будет хранить внутри блока daria_bucket все данные, извлеченные из таблицы, в нескольких файлах с именем test000000000000, test000000000001, test000000000002,... testX.

Шаг 3

Затем перейдите в хранилище, и вы увидите ведро.

GCS bucket

Зайдите внутрь него, и вы найдете один (или более) файл (ы). Затем вы можете скачать оттуда.