Каков наилучший способ переноса данных из BigTable / GAE Datastore в RDBMS?

#mysql #google-app-engine #google-cloud-datastore

#mysql #google-app-engine #google-cloud-datastore

Вопрос:

Теперь, когда Google объявил о доступности облачного хранилища SQL для app Engine, каков будет наилучший способ переноса существующих данных из BigTable / GAE Datastore в MySQL?

Чтобы ответить на отличные вопросы, поднятые Питером:

  • В моем конкретном сценарии я сохранил свою модель данных очень реляционной.
  • Я согласен с отключением моего сайта на несколько часов для перехода или, по крайней мере, предупреждением людей о том, что любые изменения, которые они вносят в течение следующих нескольких часов, будут потеряны из-за обслуживания базы данных и т.д.
  • Мой набор данных не очень большой — на главной панели управления моего приложения указано 67 ГБ, а на странице статистики хранилища данных указано, что это больше похоже на 200 МБ.
  • Я использую python.
  • Я не использую blobstore (хотя я думаю, что это отдельный вопрос от миграции чистого хранилища данных — можно перенести использование хранилища данных в MySQL при сохранении blobstore).
  • Я был бы не против заплатить разумную сумму (скажем, менее 100 долларов).
  • Я считаю, что мое приложение является ведущим / ведомым — оно было создано во время предварительного просмотра App Engine. Кажется, я не могу найти простой способ проверить это.

Похоже, что средство массовой загрузки должно использоваться для загрузки данных в текстовый формат, который затем может быть загружен с помощью mysqlimport, но у меня нет никакого опыта работы с любой технологией. Кроме того, похоже, что Cloud SQL поддерживает только импорт mysqldumps, поэтому мне пришлось бы установить MqSQL локально, mysqlimport данные, затем их сброс, затем импортировать дамп?

Пример моего текущего кода модели, на случай, если это потребуется:

 class OilPatternCategory(db.Model):
    version = db.IntegerProperty(default=1)
    user = db.UserProperty()
    name = db.StringProperty(required=True)
    default = db.BooleanProperty(default=False)

class OilPattern(db.Model):
    version = db.IntegerProperty(default=2)
    user = db.UserProperty()
    name = db.StringProperty(required=True)
    length = db.IntegerProperty()
    description = db.TextProperty()
    sport = db.BooleanProperty(default=False)
    default = db.BooleanProperty(default=False)
    retired = db.BooleanProperty(default=False)
    category = db.CategoryProperty()

class League(db.Model):
    version = db.IntegerProperty(default=1)
    user = db.UserProperty(required=True)
    name = db.StringProperty(required=True)
    center = db.ReferenceProperty(Center)
    pattern = db.ReferenceProperty(OilPattern)
    public = db.BooleanProperty(default=True)
    notes = db.TextProperty()

class Tournament(db.Model):
    version = db.IntegerProperty(default=1)
    user = db.UserProperty(required=True)
    name = db.StringProperty(required=True)
    center = db.ReferenceProperty(Center)
    pattern = db.ReferenceProperty(OilPattern)
    public = db.BooleanProperty(default=True)
    notes = db.TextProperty()

class Series(db.Model):
    version = db.IntegerProperty(default=3)
    created = db.DateTimeProperty(auto_now_add=True)
    user = db.UserProperty(required=True)
    date = db.DateProperty()
    name = db.StringProperty()
    center = db.ReferenceProperty(Center)
    pattern = db.ReferenceProperty(OilPattern)
    league = db.ReferenceProperty(League)
    tournament = db.ReferenceProperty(Tournament)
    public = db.BooleanProperty(default=True)
    notes = db.TextProperty()
    allow_comments = db.BooleanProperty(default=True)
    complete = db.BooleanProperty(default=False)
    score = db.IntegerProperty(default=0)

class Game(db.Model):
    version = db.IntegerProperty(default=5)
    user = db.UserProperty(required=True)
    series = db.ReferenceProperty(Series)
    score = db.IntegerProperty()
    game_number = db.IntegerProperty()
    pair = db.StringProperty()
    notes = db.TextProperty()
    entry_mode = db.StringProperty(choices=entry_modes, default=default_entry_mode)
  

Комментарии:

1. это довольно открытый вопрос и, возможно, немного преждевременный. Например, все эти факторы могут повлиять на ответ — сколько данных у вас есть? вам нужно поддерживать работоспособность вашего приложения во время миграции? Вам нужно преобразовать данные, чтобы они соответствовали реляционной модели, а не модели сущностей? вы используете python или Java? используете ли вы blobstore? готовы ли вы заплатить, чтобы сделать это быстро, или вы хотите ограничить это, чтобы это происходило в пределах вашей бесплатной квоты? вы уже переключились на HRD?

2. У вас вообще есть доступ к ограниченному просмотру? (если нет, вы можете подождать, пока люди действительно не воспользуются сервисом, так как тогда вы получите более подробную информацию.)

3. @Peter это полезный контрольный список

4. @Peter I предоставил больше подробностей для моей ситуации. Я зарегистрировался на ограниченный предварительный просмотр — мне не был предоставлен доступ, но в какой-то момент я захочу это сделать.

5. @PeterRecore Теперь у меня есть доступ к ограниченному просмотру.

Ответ №1:

Рассматривали ли вы возможность использования Map Reduce framework? Вы могли бы написать картографы, которые хранят объекты хранилища данных в CloudSQL. Не забудьте добавить столбец для ключа хранилища данных, это может помочь вам избежать дублирования строк или определить недостающие строки.

Вы могли бы взглянуть наhttps://github.com/hudora/gaetk_replication для ознакомления с функциями mapper.