Модуль 3. Миграция с Google Cloud NDB на Cloud Datastore

1. Обзор

Эта серия учебных пособий (практических руководств для самостоятельного обучения) призвана помочь разработчикам Google App Engine (стандартная среда) модернизировать свои приложения, проведя их через серию миграций. Наиболее важным шагом является отказ от исходных комплексных служб среды выполнения, поскольку среды выполнения следующего поколения более гибкие и предоставляют пользователям более широкий выбор вариантов обслуживания. Переход на среду выполнения нового поколения позволяет упростить интеграцию с продуктами Google Cloud, использовать более широкий спектр поддерживаемых сервисов и поддерживать текущие языковые версии.

В этом дополнительном руководстве разработчикам показано, как перейти с Cloud NDB на Cloud Datastore в качестве клиентской библиотеки для взаимодействия со службой Datastore. Разработчики, предпочитающие NDB, могут использовать его, поскольку он совместим с Python 3, поэтому эта миграция не является обязательной. Этот переход предназначен только для тех, кто хочет создать согласованную базу кода и общие библиотеки с другими приложениями, уже использующими Cloud Datastore. Это объясняется в разделе «Предыстория».

Вы узнаете, как

  • Используйте Cloud NDB (если вы с ним не знакомы)
  • Миграция с Cloud NDB на Cloud Datastore
  • Дальнейший перенос вашего приложения на Python 3.

Что вам понадобится

  • Проект Google Cloud Platform с активным платежным аккаунтом GCP.
  • Базовые навыки Python
  • Знание основных команд Linux
  • Базовые знания разработки и развертывания приложений App Engine.
  • Рабочее приложение App Engine 2.x или 3.x Модуля 2.

Опрос

Как вы будете использовать эту кодовую лабораторию?

Только прочитай это Прочитайте его и выполните упражнения.

2. Предыстория

Хотя Cloud NDB — отличное решение для хранилища данных для опытных разработчиков App Engine и помогает при переходе на Python 3, это не единственный способ, с помощью которого разработчики App Engine могут получить доступ к Datastore. Когда в 2013 году Datastore App Engine стал отдельным продуктом , Google Cloud Datastore , была создана новая клиентская библиотека , чтобы все пользователи могли использовать Datastore.

Разработчикам Python 3 App Engine и сторонним разработчикам рекомендуется использовать Cloud Datastore (а не Cloud NDB). Разработчикам App Engine Python 2 рекомендуется перейти с ndb на Cloud NDB и оттуда перейти на Python 3, но они также могут выбрать дальнейший переход на Cloud Datastore. Это логичное решение, особенно для разработчиков, у которых уже есть код, использующий Cloud Datastore, например только что упомянутый, и которые хотят создавать общие библиотеки для всех своих приложений. Повторное использование кода, как и согласованность кода, является лучшей практикой, и оба они способствуют общему снижению затрат на обслуживание, как показано ниже:

Миграция из Cloud NDB в Cloud Datastore

  • Позволяет разработчикам сосредоточиться на единой базе кода для доступа к хранилищу данных.
  • Позволяет избежать поддержки некоторого кода с помощью Cloud NDB и других с помощью Cloud Datastore.
  • Обеспечивает большую согласованность кодовой базы и лучшую возможность повторного использования кода.
  • Позволяет использовать общие/разделяемые библиотеки, что способствует снижению общих затрат на обслуживание.

Эта миграция включает в себя следующие основные шаги:

  1. Настройка/Предварительная работа
  2. Замените Cloud NDB клиентскими библиотеками Cloud Datastore
  3. Обновить приложение

3. Настройка/Предварительная работа

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

1. Проект установки

Если вы завершили лабораторную работу по Модулю 2 , мы рекомендуем повторно использовать тот же проект (и код). Альтернативно вы можете создать новый проект или повторно использовать другой существующий проект. Убедитесь, что у проекта есть активный платежный аккаунт и включен App Engine (приложение).

2. Получите базовый образец приложения.

Одним из обязательных условий является наличие работающего примера приложения Модуля 2. Используйте свое решение, если вы прошли это руководство. Вы можете завершить его сейчас (ссылка выше) или, если хотите пропустить его, скопировать репозиторий Модуля 2 (ссылка ниже).

Независимо от того, используете ли вы свой или наш, мы НАЧНЕМ с кода Модуля 2. Эта лаборатория кода Модуля 3 проведет вас через каждый шаг, и по завершении она должна напоминать код в точке ФИНИШ. Существуют версии этого руководства для Python 2 и 3, поэтому возьмите правильный репозиторий кода ниже.

Питон 2

Каталог файлов STARTing модуля 2 Python 2 (ваших или наших) должен выглядеть следующим образом:

$ ls
README.md               appengine_config.py     requirements.txt
app.yaml                main.py                 templates

Если вы прошли обучение по Модулю 2, у вас также будет папка lib с Flask и его зависимостями. Если у вас нет папки lib , создайте ее с помощью команды pip install -t lib -r requirements.txt чтобы мы могли развернуть это базовое приложение на следующем шаге. Если у вас установлены как Python 2, так и Python 3, мы рекомендуем использовать pip2 вместо pip , чтобы избежать путаницы с Python 3.

Питон 3

Каталог файлов STARTing модуля 2 Python 3 (ваших или наших) должен выглядеть следующим образом:

$ ls
README.md               main.py                 templates
app.yaml                requirements.txt

Ни lib , ни appengine_config.py не используются для Python 3.

3. (Повторно) разверните приложение Модуля 2.

Оставшиеся подготовительные шаги, которые необходимо выполнить сейчас:

  1. Повторно ознакомьтесь с инструментом командной строки gcloud (если необходимо).
  2. (Повторно) разверните код Модуля 1 в App Engine (если необходимо).

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

4. Замените Cloud NDB клиентскими библиотеками Cloud Datastore.

Единственное изменение конфигурации — это небольшая замена пакета в файле requirements.txt .

1. Обновите requirements.txt

После завершения Модуля 2 ваш файл requirements.txt выглядел следующим образом:

  • ДО (Python 2 и 3):
Flask==1.1.2
google-cloud-ndb==1.7.1

Обновите requirements.txt , заменив библиотеку Cloud NDB ( google-cloud-ndb ) последней версией библиотеки Cloud Datastore ( google-cloud-datastore ), оставив запись для Flask нетронутой, учитывая окончательную версию Cloud Datastore. совместимость с Python 2 — 1.15.3:

  • ПОСЛЕ (Python 2):
Flask==1.1.2
google-cloud-datastore==1.15.3
  • ПОСЛЕ (Python 3):
Flask==1.1.2
google-cloud-datastore==2.1.0

Имейте в виду, что репозиторий поддерживается более регулярно, чем это руководство, поэтому вполне возможно, что файл requirements.txt может отражать более новые версии. Мы рекомендуем использовать последние версии каждой библиотеки, но если они не работают, вы можете вернуться к более старой версии. Номера версий, указанные выше, являются последними на момент последнего обновления этой лаборатории кода.

2. Другие файлы конфигурации

Другие файлы конфигурации, app.yaml и appengine_config.py , должны остаться неизменными по сравнению с предыдущим шагом миграции:

  • app.yaml должен (по-прежнему) ссылаться на сторонние пакеты grpcio и setuptools .
  • appengine_config.py должен (по-прежнему) указывать pkg_resources и google.appengine.ext.vendor на сторонние ресурсы в lib .

Теперь перейдем к файлам приложения.

5. Обновите файлы приложения.

В template/index.html изменений нет, но есть несколько обновлений для main.py

1. Импорт

Начальный код раздела импорта должен выглядеть следующим образом:

  • ДО:
from flask import Flask, render_template, request
from google.cloud import ndb

Замените импорт google.cloud.ndb импортом для Cloud Datastore: google.cloud.datastore . Поскольку клиентская библиотека хранилища данных не поддерживает автоматическое создание поля метки времени в сущности, также импортируйте модуль datetime стандартной библиотеки, чтобы создать его вручную. По соглашению, импорт стандартных библиотек превосходит импорт сторонних пакетов. Когда вы закончите вносить эти изменения, это должно выглядеть так:

  • ПОСЛЕ:
from datetime import datetime
from flask import Flask, render_template, request
from google.cloud import datastore

2. Инициализация и модель данных

После инициализации Flask пример приложения Модуля 2, создающий класс модели данных NDB, и его поля выглядят следующим образом:

  • ДО:
app = Flask(__name__)
ds_client = ndb.Client()

class Visit(ndb.Model):
    visitor   = ndb.StringProperty()
    timestamp = ndb.DateTimeProperty(auto_now_add=True)

В библиотеке Cloud Datastore нет такого класса, поэтому удалите объявление класса Visit . Вам по-прежнему нужен клиент для связи с Datastore, поэтому измените ndb.Client() на datastore.Client() . Библиотека Datastore более «гибкая», позволяя создавать сущности без «предварительного объявления» их структуры, как в NDB. После этого обновления эта часть main.py должна выглядеть так:

  • ПОСЛЕ:
app = Flask(__name__)
ds_client = datastore.Client()

3. Доступ к хранилищу данных

Миграция в Cloud Datastore требует изменения способа создания, хранения и запроса объектов Datastore (на уровне пользователя). Для ваших приложений сложность этой миграции зависит от того, насколько сложен код вашего хранилища данных. В нашем примере приложения мы постарались сделать обновление максимально простым. Вот наш стартовый код:

  • ДО:
def store_visit(remote_addr, user_agent):
    with ds_client.context():
        Visit(visitor='{}: {}'.format(remote_addr, user_agent)).put()

def fetch_visits(limit):
    with ds_client.context():
        return (v.to_dict() for v in Visit.query().order(
                -Visit.timestamp).fetch_page(limit)[0])

С помощью Cloud Datastore создайте общий объект, идентифицируя сгруппированные объекты в вашем объекте с помощью «ключа». Создайте запись данных с помощью объекта JSON (Python dict ) пар ключ-значение, затем запишите ее в хранилище данных с ожидаемым put() . Запросы аналогичны, но более просты в Datastore. Здесь вы можете увидеть, чем отличается эквивалентный код Datastore:

  • ПОСЛЕ:
def store_visit(remote_addr, user_agent):
    entity = datastore.Entity(key=ds_client.key('Visit'))
    entity.update({
        'timestamp': datetime.now(),
        'visitor': '{}: {}'.format(remote_addr, user_agent),
    })
    ds_client.put(entity)

def fetch_visits(limit):
    query = ds_client.query(kind='Visit')
    query.order = ['-timestamp']
    return query.fetch(limit=limit)

Обновите тела функций store_visit() и fetch_visits() как указано выше, сохранив их подписи идентичными предыдущей версии. В главном обработчике root() нет никаких изменений. После внесения этих изменений ваше приложение теперь готово к использованию Cloud Datastore и готово к тестированию.

6. Подведение итогов/очистка

Развернуть приложение

Повторно разверните приложение с помощью gcloud app deploy и убедитесь, что приложение работает. Теперь ваш код должен соответствовать тому, что находится в папках репозитория Модуля 3:

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

приложение Visitme

Поздравляем с завершением этой лабораторной работы по Модулю 3. Теперь вы знаете, что для доступа к Datastore можно использовать клиентские библиотеки Cloud NDB и Cloud Datastore. Перейдя на последнее, вы теперь можете получить такие преимущества, как общие библиотеки, общий код и его повторное использование для обеспечения согласованности и снижения затрат на обслуживание.

Дополнительно: очистка

А как насчет очистки, чтобы избежать выставления счетов до тех пор, пока вы не будете готовы перейти к следующей лаборатории кода миграции? Как существующие разработчики, вы, вероятно, уже в курсе ценовой информации App Engine .

Необязательно: отключить приложение

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

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

Следующие шаги

Отсюда вы можете изучить следующие модули миграции:

  • Бонус модуля 3. Перейдите к бонусному разделу, чтобы узнать, как выполнить перенос на Python 3 и среду выполнения App Engine следующего поколения.
  • Модуль 7. Очереди задач App Engine Push (требуется, если вы используете очереди задач [push])
    • Добавляет taskqueue задач App Engine в приложение модуля 1.
    • Готовит пользователей к переходу на облачные задачи в модуле 8.
  • Модуль 4. Переход на Cloud Run с помощью Docker
    • Контейнеризируйте свое приложение для работы в облаке. Запускайте с Docker.
    • Позволяет вам оставаться на Python 2
  • Модуль 5. Переход на Cloud Run с помощью Cloud Buildpacks
    • Контейнеризируйте свое приложение для запуска в облаке. Запускайте с помощью Cloud Buildpacks.
    • Не нужно ничего знать о Docker, контейнерах или Dockerfile .
    • Требуется, чтобы вы уже перенесли свое приложение на Python 3.
  • Модуль 6: Миграция в Cloud Firestore
    • Перейдите в Cloud Firestore, чтобы получить доступ к функциям Firebase.
    • Хотя Cloud Firestore поддерживает Python 2, эта кодовая лаборатория доступна только в Python 3.

7. БОНУС: переход на Python 3.

Чтобы получить доступ к новейшей среде выполнения и функциям App Engine, мы рекомендуем вам перейти на Python 3. В нашем примере приложения Datastore был единственной встроенной службой, которую мы использовали, и поскольку мы перешли с ndb на Cloud NDB, теперь мы можем порт в среду выполнения App Engine Python 3.

Обзор

Хотя портирование на Python 3 не входит в рамки руководства по Google Cloud, эта часть лаборатории кода дает разработчикам представление о том, чем отличается среда выполнения Python 3 App Engine. Одной из выдающихся особенностей среды выполнения следующего поколения является упрощенный доступ к сторонним пакетам: нет необходимости указывать встроенные пакеты в app.yaml или копировать или загружать невстроенные библиотеки; они устанавливаются неявно из списка в requirements.txt .

Поскольку наш образец настолько прост , а Cloud Datastore совместим с Python 2–3, код приложения не требуется явно переносить на 3.x: приложение работает на версиях 2.x и 3.x без изменений, то есть единственные необходимые изменения происходят в конфигурации. в этом случае:

  1. Упростите app.yaml , чтобы он ссылался на Python 3, и удалите ссылку на встроенные сторонние библиотеки.
  2. Удалите appengine_config.py и папку lib , поскольку они больше не нужны.

Файлы приложений main.py и templates/index.html остаются без изменений.

Обновить requirements.txt

Последняя версия облачного хранилища данных, поддерживающая Python 2, — 1.15.3. Обновите requirements.txt последней версией для Python 3 (возможно, уже более новой). На момент написания этого руководства последней версией была 2.1.0, поэтому отредактируйте эту строку так, чтобы она выглядела следующим образом (или какой бы то ни было последней версии):

google-cloud-datastore==2.1.0

Упростите app.yaml

ДО:

Единственное реальное изменение в этом примере приложения — значительное сокращение app.yaml . Напомним, вот что у нас было в app.yaml по завершении Модуля 3 :

runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /.*
  script: main.app

libraries:
- name: grpcio
  version: 1.0.0
- name: setuptools
  version: 36.6.0

ПОСЛЕ:

В Python 3 все директивы threadsafe , api_version libraries устарели; все приложения считаются потокобезопасными, а api_version не используется в Python 3. В службах App Engine больше не предустановлены встроенные сторонние пакеты, поэтому libraries также устарели. Дополнительную информацию об этих изменениях можно найти в документации по изменениям в app.yaml . В результате вам следует удалить все три из app.yaml и обновиться до поддерживаемой версии Python 3 (см. ниже).

Необязательно: использование директивы handlers .

Кроме того, директива handlers , которая направляет трафик в приложения App Engine, также устарела. Поскольку среда выполнения следующего поколения ожидает, что веб-платформы будут управлять маршрутизацией приложений, все «скрипты-обработчики» необходимо изменить на « auto ». Объединив изменения, описанные выше, вы получите такой app.yaml :

runtime: python38

handlers:
- url: /.*
  script: auto

Дополнительные сведения о script: auto можно найти на справочной странице app.yaml .

Удаление директивы handlers

Поскольку handlers устарели, вы также можете удалить весь раздел, оставив app.yaml в одну строку:

runtime: python38

По умолчанию будет запущен веб-сервер Gunicorn WSGI , доступный для всех приложений. Если вы знакомы с gunicorn , эта команда выполняется при запуске по умолчанию с помощью базового app.yaml :

gunicorn main:app --workers 2 -c /config/gunicorn.py

Необязательно: использование директивы entrypoint

Однако если вашему приложению требуется определенная команда запуска, ее можно указать с помощью директивы entrypoint , в результате чего app.yaml будет выглядеть следующим образом:

runtime: python38
entrypoint: python main.py

В этом примере специально требуется использовать сервер разработки Flask вместо gunicorn . Код, запускающий сервер разработки, также необходимо добавить в ваше приложение для запуска на интерфейсе 0.0.0.0 через порт 8080, добавив этот небольшой раздел в конец файла main.py :

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080, debug=True)

Узнайте больше о entrypoint на справочной странице app.yaml . Дополнительные примеры и рекомендации можно найти в документации по запуску стандартной среды App Engine , а также в документации по запуску гибкой среды App Engine .

Удалите appengine_config.py и lib

Удалите файл appengine_config.py и папку lib . При переходе на Python 3 App Engine получает и устанавливает пакеты, перечисленные в requirements.txt .

Файл конфигурации appengine_config.py используется для распознавания сторонних библиотек/пакетов, независимо от того, скопировали ли вы их самостоятельно или используете уже доступные на серверах App Engine (встроенные). При переходе на Python 3 краткое изложение больших изменений:

  1. Нет объединения скопированных сторонних библиотек (перечисленных в requirements.txt ).
  2. Нет pip install в папку lib , что означает отсутствие периода в папке lib
  3. В app.yaml нет списка встроенных сторонних библиотек.
  4. Нет необходимости ссылаться на приложение на сторонние библиотеки, поэтому файл appengine_config.py отсутствует.

Все, что нужно, — это перечислить все необходимые сторонние библиотеки в requirements.txt .

Развернуть приложение

Повторно разверните приложение, чтобы убедиться, что оно работает. Вы также можете подтвердить, насколько ваше решение близко к примеру кода Python 3 из Модуля 3 . Чтобы визуализировать различия с Python 2, сравните код с его версией Python 2 .

Поздравляем с завершением бонусного этапа Модуля 3! Посетите документацию по подготовке файлов конфигурации для среды выполнения Python 3 . Наконец, просмотрите приведенное выше краткое описание дальнейших шагов и очистки.

Подготовка вашего приложения

Когда придет время перенести ваше приложение, вам придется перенести файл main.py и другие файлы приложения в версию 3.x, поэтому рекомендуется приложить все усилия, чтобы сделать ваше приложение 2.x максимально «совместимым с предыдущими версиями», как возможный.

Есть множество онлайн-ресурсов, которые помогут вам в этом, но вот некоторые ключевые советы:

  1. Убедитесь, что все зависимости приложения полностью совместимы с 3.x.
  2. Убедитесь, что ваше приложение работает как минимум на версии 2.6 (предпочтительно 2.7).
  3. Убедитесь, что приложение прошло весь набор тестов (и покрытие минимум 80%).
  4. Используйте библиотеки совместимости, такие как six , Future и/или Modernize.
  5. Узнайте о ключевых различиях между версиями 2.x и 3.x, несовместимыми с предыдущими версиями.
  6. Любой ввод-вывод, скорее всего, приведет к несовместимости Unicode и байтовых строк.

Пример приложения был разработан с учетом всего этого, поэтому приложение работает на версиях 2.x и 3.x прямо из коробки, чтобы мы могли сосредоточиться на том, чтобы показать вам, что необходимо изменить, чтобы использовать платформу следующего поколения. .

8. Дополнительные ресурсы

Проблемы и отзывы о модуле миграции App Engine

Если вы обнаружите какие-либо проблемы с этой кодовой лабораторией, сначала найдите свою проблему, прежде чем подавать заявку. Ссылки для поиска и создания новых задач:

Миграционные ресурсы

Ссылки на папки репозитория для Модуля 2 (НАЧАЛО) и Модуля 3 (ФИНИШ) можно найти в таблице ниже. Доступ к ним также можно получить из репозитория для всех миграций App Engine , которые можно клонировать или загрузить в виде ZIP-файла.

Кодлаб

Питон 2

Питон 3

Модуль 2

код

код

Модуль 3

код

код

Ресурсы App Engine

Ниже приведены дополнительные ресурсы, касающиеся этой конкретной миграции: