One place for hosting & domains

      данных

      Создание резервных копий, восстановление и миграция базы данных MongoDB в Ubuntu 20.04


      Автор выбрал COVID-19 Relief Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      MongoDB — одна из самых популярных систем управления базами данных NoSQL. Она отличается масштабируемостью, отказоустойчивостью, надежностью и удобством в использовании. В этом учебном модуле вы создадите резервную копию, восстановите и перенесете образец базы данных MongoDB.

      Импортирование и экспорт базы данных подразумевают работу с данными в формате, приемлемом для чтения, который также совместим с другими программными продуктами. Операции резервного копирования и восстановления MongoDB создают или используют специальные двоичные данные MongoDB, в результате чего не только обеспечиваются согласованность и целостность данных, но и сохраняются специальные атрибуты MongoDB. Таким образом, для переноса данных предпочтительнее использовать процесс резервного копирования и восстановления, если исходные и целевые системы совместимы друг с другом.

      Предварительные требования

      Перед выполнением этого учебного модуля необходимо следующее:

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

      Шаг 1 — Использование JSON и BSON в MongoDB

      Прежде чем продолжить прохождение этого учебного модуля, важно понять некоторые базовые моменты. Если у вас есть опыт работы с другими системами баз данных NoSQL, такими как Redis, вы можете найти некоторое сходство с ними при работе с MongoDB.

      MongoDB использует для хранения информации форматы JSON и BSON (двоичный JSON). JSON – это удобный для прочтения человеком формат, идеально подходящий для экспорта и импорта данных. Вы сможете управлять экспортированными данными в этом формате с помощью любого инструмента, поддерживающего JSON, включая простой текстовый редактор.

      Пример документа JSON:

      Example of JSON Format

      {"address":[
          {"building":"1007", "street":"Park Ave"},
          {"building":"1008", "street":"New Ave"},
      ]}
      

      С JSON удобно работать, но этот формат поддерживает не все типы данных, доступные в BSON. Это означает, что при использовании JSON возможна так называемая потеря корректности информации. Для создания резервных копий и восстановления, лучше использовать двоичный формат BSON.

      Во-вторых, вам не нужно беспокоиться о явном создании базы данных MongoDB. Если база данных, которую вы указываете для импорта, еще не существует, она создается автоматически. Еще лучше обстоят дела со структурой коллекций (таблицы базы данных). В отличие от других СУБД, в MongoDB структура создается автоматически при вставке первого документа (строка базы данных).

      В-третьих, в MongoDB операции чтения или вставки больших объемов данных, таких как в задачах этого учебного модуля, могут потреблять много ресурсов процессора, памяти и дискового пространства. Это крайне важно, поскольку MongoDB часто используется для крупных баз данных и больших данных. Самое простое решение этой проблемы — выполнять экспорт и создавать резервные копии в ночное время или в периоды низкой нагрузки.

      В-четвертых, согласованность информации может представлять проблему, если у вас загруженный сервер MongoDB, где информация может изменяться при экспорте или резервном копировании базы данных. Одно из возможных решений этой проблемы — репликация, и вы можете использовать его, когда лучше освоитесь с MongoDB.

      Хотя вы можете использовать функции импорта и экспорта для резервного копирования и восстановления данных, существуют и лучшие способы обеспечения полной целостности данных в базах данных MongoDB. Чтобы создать резервную копию данных, вам следует использовать команду mongodump. Для восстановления используйте команду mongorestore. Давайте посмотрим, как они работают.

      Шаг 2 — Использование mongodump для резервного копирования базы данных MongoDB

      Вначале поговорим о резервном копировании базы данных MongoDB.

      Одним из самых важных аргументов команды mongodump является аргумент --db, указывающий имя базы данных, резервную копию которой вы хотите создать. Если вы не укажете имя базы данных, mongodump создаст резервные копии всех ваших баз данных. Второй важный аргумент — это аргумент --out, определяющий каталог, в котором будут сохранены данные. Давайте создадим резервную копию базы данных newdb и сохраним ее в каталоге /var/backups/mongobackups. В идеальной ситуации все наши резервные копии будут содержаться в каталоге с текущей датой /var/backups/mongobackups/10-29-20.

      Вначале создайте каталог /var/backups/mongobackups:

      • sudo mkdir /var/backups/mongobackups

      Затем запустите команду mongodump:

      • sudo mongodump --db newdb --out /var/backups/mongobackups/`date +"%m-%d-%y"`

      Результат должен будет выглядеть следующим образом:

      Output

      2020-10-29T19:22:36.886+0000 writing newdb.restaurants to 2020-10-29T19:22:36.969+0000 done dumping newdb.restaurants (25359 documents)

      Обратите внимание, что в вышеуказанном пути каталога мы использовали формат date +"%m-%d-%y", который автоматически получает текущую дату. Это позволяет нам размещать резервные копии в каталогах вида /var/backups/10-29-20/. Это особенно удобно для автоматизации резервного копирования.

      Теперь у вас имеется полная резервная копия базы данных newdb в каталоге /var/backups/mongobackups/10-29-20/newdb/. В этой резервной копии есть все необходимое для правильного восстановления newdb и сохранения так называемой «корректности».

      Как правило, резервное копирование выполняется регулярно, и обычно это делается в периоды наименьшей нагрузки на сервер. Вы можете задать команду mongodump как задачу планировщика (cron), чтобы она выполнялась регулярно, например, каждый день в 03:03.

      Для этого откройте редактор crontab:

      Обратите внимание, что при запуске sudo crontab вы будете редактировать кроны пользователя root. Рекомендуется сделать именно это, потому что если вы настроите кроны для своего пользователя, они могут выполняться неправильно, особенно если для вашего профиля sudo требуется проверка пароля.

      Вставьте в командную строку crontab следующую команду mongodump:

      crontab

      3 3 * * * mongodump --out /var/backups/mongobackups/`date +"%m-%d-%y"`
      

      В приведенной выше команде мы целенаправленно опускаем аргумент --db, потому что обычно мы хотим создать резервные копии всех наших баз данных.

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

      Например, вы можете использовать следующую команду bash для удаления всех резервных копий старше семи дней:

      • find /var/backups/mongobackups/ -mtime +7 -exec rm -rf {} ;

      Аналогично предыдущей команде mongodump, вы можете добавить эту команду как задание cron. Его следует запускать непосредственно перед началом следующего резервного копирования, например, в 03:01. Для этого снова откройте crontab:

      Вставьте следующую строку:

      crontab

      1 3 * * * find /var/backups/mongobackups/ -mtime +7 -exec rm -rf {} ;
      

      Сохраните и закройте файл.

      Выполнение всех задач, описанных на этом шаге, обеспечит надлежащее решение резервного копирования для ваших баз данных MongoDB.

      Шаг 3 — Использование mongorestore для восстановления и переноса базы данных MongoDB

      При восстановлении базы данных MongoDB из предыдущей резервной копии вы получите точную копию информации MongoDB на определенный момент времени, включая все индексы и типы данных. Это особенно полезно, если вы хотите выполнить миграцию ваших баз данных MongoDB. Для восстановления MongoDB мы будем использовать команду mongorestore, которая работает с двоичными резервными копиями, которые производятся mongodump.

      Давайте продолжим наши примеры с базой данных newdb и посмотрим, как мы можем восстановить ее с предыдущей резервной копии. Вначале мы укажем имя базы данных с аргументом --nsInclude. Если использовать newdb.*, мы восстановим все коллекции. Для восстановления отдельной коллекции, например restaurants, следует использовать newdb.restaurants.

      Используя аргумент --drop мы обеспечим предварительное отбрасывание целевой базы данных так, чтобы резервная копия была восстановлена в чистой базе данных. Как последний аргумент мы зададим каталог последней резервной копии, который будет выглядеть примерно так: /var/backups/mongobackups/10-29-20/newdb/.

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

      • sudo mongorestore --db newdb --drop /var/backups/mongobackups/10-29-20/newdb/

      Результат должен будет выглядеть следующим образом:

      Output

      2020-10-29T19:25:45.825+0000 the --db and --collection args should only be used when restoring from a BSON file. Other uses are deprecated and will not exist in the future; use --nsInclude instead 2020-10-29T19:25:45.826+0000 building a list of collections to restore from /var/backups/mongobackups/10-29-20/newdb dir 2020-10-29T19:25:45.829+0000 reading metadata for newdb.restaurants from /var/backups/mongobackups/10-29-20/newdb/restaurants.metadata.json 2020-10-29T19:25:45.834+0000 restoring newdb.restaurants from /var/backups/mongobackups/10-29-20/newdb/restaurants.bson 2020-10-29T19:25:46.130+0000 no indexes to restore 2020-10-29T19:25:46.130+0000 finished restoring newdb.restaurants (25359 documents) 2020-10-29T19:25:46.130+0000 done

      В примере выше мы восстанавливаем данные на том же сервере, на котором создали резервную копию. Если вы хотите перенести данные на другой сервер, используя эту же методику, вам следует скопировать на другой сервер каталог резервной копии, в нашем случае это /var/backups/mongobackups/10-29-20/newdb/.

      Заключение

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



      Source link

      Импорт и экспорт базы данных MongoDB в Ubuntu 20.04


      Автор выбрал COVID-19 Relief Fund для получения пожертвования в рамках программы Write for DOnations.

      Введение

      MongoDB — одна из самых популярных СУБД NoSQL. Она отличается масштабируемостью, мощностью и надежностью и удобством в использовании. В этом учебном модуле мы покажем, как импортировать и экспортировать ваши базы данных MongoDB.

      Следует отметить, что под импортом и экспортом мы подразумеваем операции с данными в удобном для чтения формате, совместимом с другими программными продуктами. В отличие от импорта и экспорта, операции резервного копирования и восстановления используют специальные двоичные данные MongoDB, обеспечивающие согласованность и целостность данных и сохраняющие специальные атрибуты MongoDB. Таким образом, для переноса данных предпочтительнее использовать процесс резервного копирования и восстановления, если исходные и целевые системы совместимы друг с другом.

      В этом учебном модуле мы не описываем задачи резервного копирования, восстановления и миграции. Более подробную информацию можно найти в учебном модуле Резервное копирование, восстановление и миграция баз данных MongoDB в Ubuntu 20.04.

      Предварительные требования

      Для этого учебного модуля вам потребуется следующее:

      Шаг 1 — Импортирование информации в MongoDB

      Чтобы узнать, как работает импорт информации в MongoDB, мы используем популярный образец базы данных MongoDB — базу о ресторанах. Эта база имеет формат json, и ее можно загрузить с помощью wget следующим образом:

      • wget https://raw.githubusercontent.com/mongodb/docs-assets/primer-dataset/primer-dataset.json

      После завершения загрузки в текущем каталоге должен быть файл primer-dataset.json (размер 12 Мбайт). Импортируем данные из этого файла в новую базу данных newdb и в коллекцию restaurants.

      Используйте команду mongoimport следующим образом:

      • sudo mongoimport --db newdb --collection restaurants --file primer-dataset.json

      Результат будет выглядеть вот так:

      Output

      2020-11-11T19:37:55.607+0000 connected to: mongodb://localhost/ 2020-11-11T19:37:57.841+0000 25359 document(s) imported successfully. 0 document(s) failed to import

      Как показывает приведенная выше команда, были импортированы 25359 документов. Поскольку у нас не было базы данных с именем newdb, MongoDB создала ее автоматически.

      Давайте проверим импорт.

      Подключитесь к только что созданной базе данных newdb:

      Вы подключились к экземпляру базы данных newdb. Обратите внимание, что ваша командная строка изменилась. Это означает, что вы подключены к базе данных.

      Подсчитайте число документов в коллекции restaraunts с помощью команды:

      Будет выведен результат 25359, т. е. количество импортированных документов. Для еще более эффективной проверки вы можете выбрать первый документ из коллекции restaraunts следующим образом:

      Результат будет выглядеть вот так:

      [secondary label Output]
      {
          "_id" : ObjectId("5fac3d937f12c471b3f26733"),
          "address" : {
              "building" : "1007",
              "coord" : [
                  -73.856077,
                  40.848447
              ],
              "street" : "Morris Park Ave",
              "zipcode" : "10462"
          },
          "borough" : "Bronx",
          "cuisine" : "Bakery",
          "grades" : [
              {
                  "date" : ISODate("2014-03-03T00:00:00Z"),
                  "grade" : "A",
                  "score" : 2
              },
      ...
          ],
          "name" : "Morris Park Bake Shop",
          "restaurant_id" : "30075445"
      }
      

      Такая детальная проверка может выявить проблемы с содержанием документа, кодировкой и т. д. Формат json использует кодировку UTF-8, и ваши операции экспорта и импорта также должны использовать эту кодировку. Это необходимо помнить при редактировании файлов json вручную. В противном случае MongoDB автоматически сделает это за вас.

      Чтобы выйти из командной строки MongoDB, введите команду exit:

      Вы вернетесь в обычную командную строку как пользователь без привилегий root.

      Шаг 2 — Экспорт информации из MongoDB

      Как мы уже упоминали, при экспорте информации MongoDB вы можете получить удобный для чтения файлы с вашими данными. По умолчанию экспорт выполняется в формате json, но также вы можете использовать для экспорта формат csv (разделенные запятыми значения).

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

      Простой пример работы команды mongoexport — экспорт коллекции restaurants из базы данных newdb, куда мы ее до этого импортировали. Это можно сделать следующим образом:

      • sudo mongoexport --db newdb -c restaurants --out newdbexport.json

      В команде выше мы используем --db для определения базы данных, -c для определения коллекции и --out для определения файла, куда будут сохранены данные.

      Вывод успешной команды mongoexport должен выглядеть вот так:

      Output

      2020-11-11T19:39:57.595+0000 connected to: mongodb://localhost/ 2020-11-11T19:39:58.619+0000 [###############.........] newdb.restaurants 16000/25359 (63.1%) 2020-11-11T19:39:58.871+0000 [########################] newdb.restaurants 25359/25359 (100.0%) 2020-11-11T19:39:58.871+0000 exported 25359 records

      Этот вывод показывает, что было экспортировано 25359 документов, то есть, столько же документов, сколько мы импортировали.

      В некоторых случаях, вам может быть нужно экспортировать только часть коллекции. Учитывая структуру и содержание файла restaurants json, давайте экспортируем все рестораны китайской кухни, расположенные в Бронксе. Если мы хотим получить эту информацию напрямую при подключении к MongoDB, нам нужно снова подключиться к базе данных:

      Затем, используйте следующий запрос:

      • db.restaurants.find( { "borough": "Bronx", "cuisine": "Chinese" } )

      Результаты будут выведены на терминал:

      Output

      • 2020-12-03T01:35:25.366+0000 connected to: mongodb://localhost/
      • 2020-12-03T01:35:25.410+0000 exported 323 records

      Чтобы выйти из диалогового окна MongoDB, введите exit:

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

      • sudo mongoexport --db newdb -c restaurants -q "{"borough": "Bronx", "cuisine": "Chinese"}" --out Bronx_Chinese_retaurants.json

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

      Если экспорт выполнен успешно, результат будет выглядеть вот так:

      Output

      2020-11-11T19:49:21.727+0000 connected to: mongodb://localhost/ 2020-11-11T19:49:21.765+0000 exported 323 records

      Выше показано, что мы экспортировали 323 записи, которые можно будет найти в заданном нами файле Bronx_Chinese_retaurants.json.

      Используйте cat и less для сканирования данных:

      • cat Bronx_Chinese_retaurants.json | less

      Используйте пробел для прокрутки страниц данных:

      Output

      • date":{"$date":"2015-01-14T00:00:00Z"},"grade":"Z","score":36}],"na{"_id":{"$oid":"5fc8402d141f5e54f9054f8d"},"address":{"building":"1236","coord":[-73.8893654,40.81376179999999],"street":"238 Spofford Ave","zipcode":"10474"},"borough":"Bronx","cuisine":"Chinese","grades":[{"date":{"$date":"2013-12-30T00:00:00Z"},"grade":"A","score":8},{"date":{"$date":"2013-01-08T00:00:00Z"},"grade":"A","score":10},{"date":{"$date":"2012-06-12T00:00:00Z"},"grade":"B","score":15}],
      • . . .

      Нажмите q, чтобы выйти. Теперь вы можете импортировать и экспортировать базу данных MongoDB.

      Заключение

      В этом учебном модуле мы познакомили вас с основами экспорта информации из базы данных MongoDB и импорта информации в эту БД. Дополнительную информацию можно найти в учебном модуле Резервное копирование, восстановление и миграция базы данных MongoDB в Ubuntu 20.04.

      Также вы можете рассмотреть возможность использования репликации. Репликация позволяет продолжить выполнение службы MongoDB без перебоев на подчиненном сервере MongoDB во время восстановления главного сервера после неисправности. Частью процесса репликации является журнал операций (oplog), где записываются все операции, изменяющие данные. Вы можете использовать этот журнал, как если бы вы использовали двоичный журнал в MySQL для восстановления данных после последнего резервного копирования. Помните, что резервное копирование обычно выполняется ночью, и если вы решите восстановить данные вечером, вы потеряете все изменения, которые произошли с момента создания резервной копии.



      Source link

      Обработка данных входящих запросов в Flask


      Введение

      Веб-приложениям часто требуется обрабатывать данные входящих запросов пользователей. Эта полезная нагрузка может иметь форму строк запросов, данных форм и объектов JSON. Flask, как и любая другая веб-инфраструктура, предоставляет доступ к данным запросов.

      В этом учебном модуле мы создадим приложение Flask с тремя маршрутами, которое будет принимать строки запросов, данные форм и объекты JSON.

      Предварительные требования

      Для данного обучающего руководства вам потребуется следующее:

      • Для данного проекта потребуется установить Python в локальной среде.
      • В этом проекте мы будем использовать инструмент Pipenv, предоставляющий отличные возможности упаковки для программирования на Python. Он предоставляет возможности Pipfile, pip и virtualenv в одной команде.
      • Для тестирования конечных точек API потребуется установить Postman или другой подобный инструмент.

      Для этого учебного модуля мы использовали версии Pipenv v2020.11.15, Python v3.9.0 и Flask v1.1.2.

      Настройка проекта

      Чтобы продемонстрировать разные способы использования запросов, мы создадим приложение Flask. Хотя в примере используется упрощенная структура отображения функций и маршрутов, уроки этого учебного модуля можно применить к любым методам организации представлений, включая представления на базе классов, эскизов или расширений, таких как Flask-Via.

      Прежде всего, вам нужно будет создать каталог для проекта. Откройте терминал и запустите следующую команду:

      • mkdir flask_request_example

      Затем перейдите в новый каталог:

      Затем установите Flask. Откройте терминал и запустите следующую команду:

      Команда pipenv создаст среду virtualenv для этого проекта, Pipfile, install flask и Pipfile.lock.

      Для активации virtualenv этого проекта запустите следующую команду:

      Чтобы получить доступ к входящим данным в Flask, вам нужно будет использовать объект request. В объекте request хранятся все входящие данные запроса, включая тип MIME, источник, IP-адрес, необработанные данные, метод HTTP, заголовки и т. д.

      Хотя вся информация в объекте request может быть полезной для наших целей, в этом учебном модуле мы уделим основное внимание данным, которые обычно предоставляются вызывающей стороной напрямую.

      Чтобы получить доступ к запрашиваемому объекту в Flask, вам потребуется импортировать его из библиотеки Flask:

      from flask import request
      

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

      Используйте редактор кода для создания файла app.py. Импортируйте Flask и объект request. Также установите маршруты для query-example, form-example и json-example:

      app.py

      # import main Flask class and request object
      from flask import Flask, request
      
      # create the Flask app
      app = Flask(__name__)
      
      @app.route('/query-example')
      def query_example():
          return 'Query String Example'
      
      @app.route('/form-example')
      def form_example():
          return 'Form Data Example'
      
      @app.route('/json-example')
      def json_example():
          return 'JSON Object Example'
      
      if __name__ == '__main__':
          # run app in debug mode on port 5000
          app.run(debug=True, port=5000)
      

      Затем откройте терминал и запустите приложение с помощью следующей команды:

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

      http://127.0.0.1:5000/query-example (or localhost:5000/query-example)
      http://127.0.0.1:5000/form-example (or localhost:5000/form-example)
      http://127.0.0.1:5000/json-example (or localhost:5000/json-example)
      

      Код устанавливает три маршрута, и при открытии каждого маршрута вы увидите сообщения "Query String Example", "Form Data Example" и "JSON Object Example".

      Использование аргументов запроса

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

      Строка запроса выглядит следующим образом:

      example.com?arg1=value1&arg2=value2
      

      Строка запроса начинается после знака (?) вопроса:

      example.com?arg1=value1&arg2=value2
      

      В ней содержатся пары ключ-значение, разделенные символом амперсанда (&):

      example.com?arg1=value1&arg2=value2
      

      В каждой паре после ключа идет знак равенства (=), а затем идет значение.

      arg1 : value1
      arg2 : value2
      

      Строки запросов полезны для передачи данных, которые не требуют действий со стороны пользователя. Вы можете сгенерировать строку запроса в своем приложении и добавить ее к URL так, чтобы при запросе пользователя данные передавались автоматически. Строка запроса также может быть сгенерирована формами, использующими метод GET.

      Давайте добавим строку запроса в маршрут query-example. В этом гипотетическом примере, мы укажем имя языка программирования, которое будет отображаться на экране. Создайте ключ "language" и значение "Python":

      http://127.0.0.1:5000/query-example?language=Python
      

      Если вы запустите приложение и перейдете к этому URL, вы увидите сообщение "Query String Example".

      Вам нужно будет программировать часть, обрабатывающую аргументы запроса. Этот код считает ключ language, используя request.args.get('language') или request.args['language'].

      При вызове request.args.get('language') приложение продолжит работу, если ключ language отсутствует по указанному URL. В этом случае данный метод будет иметь результат None.

      При вызове request.args['language'] приложение возвращает ошибку 400, если ключ language отсутствует по указанному URL.

      При работе со строками запросов, рекомендуется использовать request.args.get(), чтобы предотвратить возможные сбои в работе приложения.

      Давайте прочитаем ключ language и выведем его.

      Измените маршрут query-example в app.py с помощью следующего кода:

      app.py

      @app.route('/query-example')
      def query_example():
          # if key doesn't exist, returns None
          language = request.args.get('language')
      
          return '''<h1>The language value is: {}</h1>'''.format(language)
      

      Затем запустите приложение и перейдите к URL:

      http://127.0.0.1:5000/query-example?language=Python
      

      Браузер должен вывести следующее сообщение:

      Output

      The language value is: Python

      Аргумент из URL привязывается к переменной language, а затем возвращается через браузер.

      Чтобы добавить дополнительные параметры запроса, вы можете добавить амперсанды и новые пары ключ-значение в конце URL. Создайте ключ "framework" и значение "Flask":

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask
      

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

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
      

      Чтобы получить доступ к этим значениям, мы все равно используем request.args.get() или request.args[]. Давайте используем оба варианта, чтобы продемонстрировать, что произойдет при отсутствии ключа. Измените маршрут query_example, чтобы назначить значение результатов переменным и вывести их:

      @app.route('/query-example')
      def query_example():
          # if key doesn't exist, returns None
          language = request.args.get('language')
      
          # if key doesn't exist, returns a 400, bad request error
          framework = request.args['framework']
      
          # if key doesn't exist, returns None
          website = request.args.get('website')
      
          return '''
                    <h1>The language value is: {}</h1>
                    <h1>The framework value is: {}</h1>
                    <h1>The website value is: {}'''.format(language, framework, website)
      

      Затем запустите приложение и перейдите к URL:

      http://127.0.0.1:5000/query-example?language=Python&framework=Flask&website=DigitalOcean
      

      Браузер должен вывести следующее сообщение:

      Output

      The language value is: Python The framework value is: Flask The website value is: DigitalOcean

      Удалите ключ language из URL:

      http://127.0.0.1:5000/query-example?framework=Flask&website=DigitalOcean
      

      Браузер должен вывести следующее сообщение со словом None, если для language будет отсутствовать значение:

      Output

      The language value is: None The framework value is: Flask The website value is: DigitalOcean

      Удалите ключ framework из URL:

      http://127.0.0.1:5000/query-example?language=Python&website=DigitalOcean
      

      Браузер должен вывести сообщение об ошибке, потому что он ожидает получить значение framework:

      Output

      werkzeug.exceptions.BadRequestKeyError werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'framework'

      Теперь вы должны понимать, как следует обрабатывать строки запросов. Перейдем к следующему типу входящих данных.

      Использование данных форм

      Данные форм поступают из форм, отправленных на маршрут в виде запроса POST. Вместо отображения данных в URL (кроме случаев отправки форм в виде запроса GET) данные форм передаются приложению незаметно. Хотя вы не видите передаваемые данные форм, ваше приложение может их считывать.

      Чтобы продемонстрировать это, давайте изменим маршрут form-example в app.py так, чтобы принимать запросы GET и POST и возвращать форму:

      app.py

      # allow both GET and POST requests
      @app.route('/form-example', methods=['GET', 'POST'])
      def form_example():
          return '''
                    <form method="POST">
                        <div><label>Language: <input type="text" name="language"></label></div>
                        <div><label>Framework: <input type="text" name="framework"></label></div>
                        <input type="submit" value="Submit">
                    </form>'''
      

      Затем запустите приложение и перейдите к URL:

      http://127.0.0.1:5000/form-example
      

      Браузер должен отображать форму с двумя полями ввода: одно language и одно для framework, а также кнопку отправки.

      Важнее всего знать об этой форме то, что она выполняет запрос POST к тому же маршруту, который сгенерировал форму. Все ключи, которые считываются в приложении, поступают от атрибутов name в полях ввода формы. В этом случае language и framework являются именами полей ввода, и поэтому у вас будет доступ к ним в приложении.

      Внутри функции просмотра вам нужно будет проверить метод запроса: GET или POST. Если это запрос GET, вы можете вывести форму. В противном случае это запрос POST, и вам нужно обработать входящие данные.

      Измените маршрут form-example в app.py, добавив следующий код:

      app.py

      # allow both GET and POST requests
      @app.route('/form-example', methods=['GET', 'POST'])
      def form_example():
          # handle the POST request
          if request.method == 'POST':
              language = request.form.get('language')
              framework = request.form.get('framework')
              return '''
                        <h1>The language value is: {}</h1>
                        <h1>The framework value is: {}</h1>'''.format(language, framework)
      
          # otherwise handle the GET request
          return '''
                 <form method="POST">
                     <div><label>Language: <input type="text" name="language"></label></div>
                     <div><label>Framework: <input type="text" name="framework"></label></div>
                     <input type="submit" value="Submit">
                 </form>'''
      

      Затем запустите приложение и перейдите к URL:

      http://127.0.0.1:5000/form-example
      

      Введите в поле language значение Python, а в поле framework — значение Flask. Затем нажмите кнопку Submit.

      Браузер должен вывести следующее сообщение:

      Output

      The language value is: Python The framework value is: Flask

      Теперь вы понимаете, как обрабатывать данные формы. Перейдем к следующему типу входящих данных.

      Использование данных JSON

      Данные JSON обычно создаются процессом, который вызывает маршрут.

      Пример объекта JSON:

      {
        "language": "Python",
        "framework": "Flask",
        "website": "Scotch",
        "version_info": {
          "python": "3.9.0",
          "flask": "1.1.2"
        },
        "examples": ["query", "form", "json"],
        "boolean_test": true
      }
      

      Такая структура позволяет передавать более сложные данные, чем строки запросов и данные форм. В этом примере вы видите вложенные объекты JSON и массив элементов. Этот формат данных может обрабатываться Flask.

      Измените маршрут form-example в app.py, чтобы принимать запросы POST и игнорировать другие запросы, в частности GET:

      app.py

      @app.route('/json-example', methods=['POST'])
      def json_example():
          return 'JSON Object Example'
      

      Для строк запросов и данных форм в этом учебном модуле мы использовали браузер, но для отправки объекта JSON мы используем Postman, чтобы отправлять персонализированные запросы в URL.

      Примечание. Если вам нужна помощь в навигации по интерфейсу Postman для отправки запросов, воспользуйтесь официальной документацией.

      Добавьте URL в Postman и измените тип на POST. На вкладке body переключитесь на raw и выберите JSON из раскрывающегося списка.

      Эти настройки необходимы, чтобы Postman мог правильно отправлять данные JSON и чтобы ваше приложение Flask понимало, что получает данные JSON:

      POST http://127.0.0.1:5000/json-example
      Body
      raw JSON
      

      Затем скопируйте в поле ввода текста предыдущий пример JSON.

      Отправьте запрос. Вы должны получить ответ "JSON Object Example". Это не так интересно, но это ожидаемо, потому что код для обработки ответа данных JSON еще нужно написать.

      Чтобы читать данные, вам нужно понимать, как Flask преобразует данные JSON в структуры данных Python:

      • Все объекты конвертируются в словари Python. {"key" : "value"} в JSON соответствуют somedict['key'], который возвращает значение в Python.
      • Массив в JSON конвертируется в список в Python. Поскольку синтаксис одинаковый, приведем список примеров: [1,2,3,4,5]
      • Значения в кавычках объекта JSON станут строками в Python.
      • Логические операторы true и false становятся True и False в Python.
      • Числа без кавычек становятся числами в Python.

      Теперь давайте поработаем с кодом, чтобы считывать входящие данные JSON.

      Вначале добавим все содержимое объекта JSON в переменную, используя request.get_json().

      request.get_json() конвертирует объект JSON в данные Python. Давайте назначим данные входящего запроса в переменные и выведем их, внеся следующие изменения в маршрут json-example:

      app.py

      # GET requests will be blocked
      @app.route('/json-example', methods=['POST'])
      def json_example():
          request_data = request.get_json()
      
          language = request_data['language']
          framework = request_data['framework']
      
          # two keys are needed because of the nested object
          python_version = request_data['version_info']['python']
      
          # an index is needed because of the array
          example = request_data['examples'][0]
      
          boolean_test = request_data['boolean_test']
      
          return '''
                 The language value is: {}
                 The framework value is: {}
                 The Python version is: {}
                 The item at index 0 in the example list is: {}
                 The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
      

      Обратите внимание на процедуру доступа к элементам, находящимся не на верхнем уровне. Поскольку мы вводим вложенный объект, используется ['version']['python']. А ['examples'][0] используется для доступа к индексу 0 в массиве example.

      Если объект JSON, отправленный с запросом, не имеет ключа, доступ к которому осуществляется через функцию view, запрос не будет выполняться. Если вы не хотите, чтобы запрос выдавал сбой при отсутствии ключа, вам нужно будет проверить наличие ключа, прежде чем пытаться получить к нему доступ.

      app.py

      # GET requests will be blocked
      @app.route('/json-example', methods=['POST'])
      def json_example():
          request_data = request.get_json()
      
          language = None
          framework = None
          python_version = None
          example = None
          boolean_test = None
      
          if request_data:
              if 'language' in request_data:
                  language = request_data['language']
      
              if 'framework' in request_data:
                  framework = request_data['framework']
      
              if 'version_info' in request_data:
                  if 'python' in request_data['version_info']:
                      python_version = request_data['version_info']['python']
      
              if 'examples' in request_data:
                  if (type(request_data['examples']) == list) and (len(request_data['examples']) > 0):
                      example = request_data['examples'][0]
      
              if 'boolean_test' in request_data:
                  boolean_test = request_data['boolean_test']
      
          return '''
                 The language value is: {}
                 The framework value is: {}
                 The Python version is: {}
                 The item at index 0 in the example list is: {}
                 The boolean value is: {}'''.format(language, framework, python_version, example, boolean_test)
      

      Запустите приложение и отправьте пример запроса JSON с помощью Postman. В ответе вы увидите следующее:

      Output

      The language value is: Python The framework value is: Flask The Python version is: 3.9 The item at index 0 in the example list is: query The boolean value is: false

      Теперь вы должны понимать принципы обработки объектов JSON.

      Заключение

      В этом учебном модуле мы создали приложение Flask с тремя маршрутами, которое будет принимать строки запросов, данные форм и объекты JSON.

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

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

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



      Source link