Как загрузить данные навалом в хранилище данных appengine? Старые методы не работают

Это должно быть довольно распространенным требованием и простым процессом: загружать данные навалом в хранилище данных appengine.

однако ни одно из старых решений, упомянутых в stackoverflow (ссылки ниже*), больше не работает. Метод bulkloader, который был наиболее разумным решением при загрузке в хранилище данных с использованием API DB, не работает с API NDB

и теперь метод bulkloader, похоже, устарел и старые ссылки, которые все еще присутствующие в документах, приводят к неправильной странице. Вот пример

https://developers.google.com/appengine/docs/python/tools/uploadingdata

эта ссылка выше все еще присутствует на этой странице:https://developers.google.com/appengine/docs/python/tools/uploadinganapp

Что является рекомендуемым методом для bulkloading данных?

две возможные альтернативы кажутся 1) с помощью remote_api или 2) написание CSV файл в ведро GCS и чтение из него. У кого-нибудь есть опыт успешного использования любого метода?

любые указатели будут высоко оценены. Спасибо!

[*решения, предлагаемые по ссылкам ниже более не действительна]

[1] как можно загружать данные навалом в хранилище данных google appengine?

[2] как вставить объемные данные в хранилище данных Google App Engine?

4 ответов


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

Я закончил с помощью apache-beam (поток данных Google cloud).

вам нужно только написать несколько строк кода "beam" в

  • прочитайте свои данные (например, размещенные на облачном хранилище) - вы получите PCollection строк,
  • делайте все, что хотите (так что вы получите PCollection сущностей хранилища данных),
  • сбросить их в хранилище раковина.

посмотреть Как ускорить массовый импорт в Google cloud datastore с несколькими работниками? для конкретного случая использования.

я смог записать со скоростью 800 объектов в секунду в мое хранилище данных с 5 рабочими. Это позволило мне завершить задачу импорта (с 16 миллионами строк) в около 5 часов. Если вы хотите сделать это быстрее, используйте больше рабочих: D


метод 1: Используйте remote_api

как : написать bulkloader.и YAML файл и запустить его непосредственно с помощью "appcfg.py upload_data команда" из терминала Я не рекомендую этот метод по нескольким причинам: 1. огромные задержки 2. нет поддержки NDB

Метод 2: GCS и использование mapreduce

загрузка файла данных в GCS:

использовать "хранение-передача файлов-JSON-python " проект github (chunked_transfer.py) для загрузки файлов в gcs из локальной системы. Убедитесь в том, чтобы генерировать правильные "клиент-секреты".JSON " файл из консоли администратора App engine.

Mapreduce:

используйте "appengine-mapreduce " проект github. Скопируйте папку" mapreduce " в папку верхнего уровня проекта.

добавьте нижеприведенную строку в приложение.и YAML файл:

includes:
  - mapreduce/include.yaml

ниже ваш main.py файл

import cgi
import webapp2
import logging
import os, csv
from models import DataStoreModel
import StringIO
from google.appengine.api import app_identity
from mapreduce import base_handler
from mapreduce import mapreduce_pipeline
from mapreduce import operation as op
from mapreduce.input_readers import InputReader

def testmapperFunc(newRequest):
    f = StringIO.StringIO(newRequest)
    reader = csv.reader(f, delimiter=',')
    for row in reader:
        newEntry = DataStoreModel(attr1=row[0], link=row[1])
        yield op.db.Put(newEntry)

class TestGCSReaderPipeline(base_handler.PipelineBase):
    def run(self, filename):
        yield mapreduce_pipeline.MapreducePipeline(
                "test_gcs",
                "testgcs.testmapperFunc",
                "mapreduce.input_readers.FileInputReader",
                mapper_params={
                    "files": [filename],
                    "format": 'lines'
                },
                shards=1)

class tempTestRequestGCSUpload(webapp2.RequestHandler):
    def get(self):
        bucket_name = os.environ.get('BUCKET_NAME',
                                     app_identity.get_default_gcs_bucket_name())

        bucket = '/gs/' + bucket_name
        filename = bucket + '/' + 'tempfile.csv'

        pipeline = TestGCSReaderPipeline(filename)
        pipeline.with_params(target="mapreducetestmodtest")
        pipeline.start()
        self.response.out.write('done')

application = webapp2.WSGIApplication([
    ('/gcsupload', tempTestRequestGCSUpload),
], debug=True)

помните:

  1. проект Mapreduce использует теперь устаревший "Google Cloud Storage Files API". Поэтому поддержка в будущем не гарантируется.
  2. Map reduce добавляет небольшие накладные расходы на чтение и запись хранилища данных.

Метод 3: клиентская библиотека GCS и GCS

  1. загрузите csv / текстовый файл в gcs с помощью над методом передачи файлов.
  2. используйте клиентскую библиотеку gcs (скопируйте папку "cloudstorage" в папку верхнего уровня приложения).

добавьте приведенный ниже код в приложение main.py файл.

import cgi
import webapp2
import logging
import jinja2
import os, csv
import cloudstorage as gcs
from google.appengine.ext import ndb
from google.appengine.api import app_identity
from models import DataStoreModel

class UploadGCSData(webapp2.RequestHandler):
    def get(self):
        bucket_name = os.environ.get('BUCKET_NAME',
                                     app_identity.get_default_gcs_bucket_name())
        bucket = '/' + bucket_name
        filename = bucket + '/tempfile.csv'
        self.upload_file(filename)

    def upload_file(self, filename):
        gcs_file = gcs.open(filename)
        datareader = csv.reader(gcs_file)
        count = 0
        entities = []
        for row in datareader:
            count += 1
                newProd = DataStoreModel(attr1=row[0], link=row[1])
                entities.append(newProd)

            if count%50==0 and entities:
                ndb.put_multi(entities)
                entities=[]

        if entities:
            ndb.put_multi(entities)

application = webapp2.WSGIApplication([
    ('/gcsupload', UploadGCSData),
], debug=True)

метод удаленного API, как показано в вашей ссылке [1], по - прежнему работает нормально, хотя он очень медленный, если у вас больше нескольких сотен строк.

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


с 2018 года лучший способ сделать это-использовать новая возможность импорта / экспорта.