65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Azure 上现代化 Python 应用和数据(第五部分):数据现代化

2022 年 5 月 3 日

CPOL

8分钟阅读

viewsIcon

4844

如何创建 Cosmos DB 数据库,然后使用 Djongo Mapper 和 Cosmos DB 的 MongoDB API 改造我们的应用程序以使其正常工作

在这一系列六篇文章的前几篇中,我们学习了如何将本地 PostgreSQL 数据迁移到云托管的数据库。我们将应用程序连接修改为使用 Azure Database for PostgreSQL 而不是本地 PostgreSQL。通过运行迁移命令,我们在云端重新创建了数据库模式和数据。

本文将配置一个使用 Azure Cosmos DB API for MongoDB 的新云数据库,迁移我们的 Azure Database for PostgreSQL,并将我们的应用程序连接到新的 MongoDB 数据库。然后,我们将本地运行 Django 应用程序,同时连接到 Azure Cosmos DB 数据库,以确保一切都能正常工作。

与传统数据库相比,Azure Cosmos DB 具有许多优势。它是一个全球分布式多模型数据库,原生支持类似 JSON 的文档、键值存储、图和列族(表格)数据模型。开发人员受益于 Azure Cosmos DB 的 API 支持,能够连接各种数据库,包括 MongoDB、SQL、Graph 和 Azure Tables。

企业受益于 Azure Cosmos DB 的高可用性、吞吐量、一致性以及低延迟的读写操作。它还提供简单的自动伸缩功能,并提供有效处理灾难恢复的特性。

Azure Cosmos DB 的 MongoDB API 会自动索引所有数据,无需进行模式和索引管理,从而可以轻松地使用熟悉的 MongoDB 体验来使用 Cosmos DB。

MongoDB 比传统的关​​联数据库快得多。例如,MongoDB 支持丰富的对象模型、二级索引、复制、高可用性、原生聚合和无模式模型。另一方面,PostgreSQL 等关系数据库管理系统 (RDBMS) 在原子事务支持、连接和数据安全性方面表现出色。

按照本教程的步骤运行您的应用程序。或者,下载并打开此 GitHub 存储库文件夹,查看此第五篇文章结束时的代码。

升级项目

我们需要声明运行新代码所需的包版本。因此,请打开 `requirements.txt` 文件。将其内容替换为以下内容:

# requirements.txt file
asgiref==3.5.0
Django==3.1.4
django-cors-headers==3.10.1
djangorestframework==3.11.0
djongo==1.3.6
gunicorn==20.0.4
pymongo==3.12.1
pytz==2019.3
sqlparse==0.2.4
django-cors-middleware==1.3.1
django-extensions==3.1.5
psycopg2==2.8.6
psycopg2-binary==2.8.6
PyJWT==1.4.2
six==1.10.0

然后创建一个新的虚拟环境(如果您还没有),使用此命令:

> python -m venv .venv

接下来,使用此命令激活 `.venv` 虚拟环境:

> .venv\Scripts\activate

然后使用此命令安装所需的依赖项:

(.venv) > pip install -r requirements.txt

创建 Cosmos DB MongoDB 帐户

在新浏览器窗口中登录 Azure 门户。然后,搜索“Azure Cosmos DB”。

选择 Azure Cosmos DB 计划,然后点击 创建

选择 API 选项页面,选择 Azure Cosmos DB API for MongoDB > 创建

API 决定了要创建的帐户类型。选择 Azure Cosmos DB API for MongoDB,因为您将创建一个数据库和一系列与 MongoDB 配合使用的集合。

创建 Azure Cosmos DB 帐户 页面,输入新 Azure Cosmos DB 帐户 的设置,例如 资源组帐户名称,然后点击 审阅 + 创建

接下来,点击 转到资源 链接,等待几分钟,直到 Azure 创建帐户。等待门户显示您新的 Cosmos DB 帐户的概览。

我们仍然需要创建 Mongo DB 数据库。因此,点击左侧菜单上的 数据资源管理器

然后在中心面板上点击 新建数据库 链接。

将数据库命名为“conduit_db”。将 数据库吞吐量 配置为 手动,然后点击 确定 保存数据库。

连接到 Cosmos DB 帐户并应用迁移

将我们的 Python 应用程序当前指向关​​联数据库的数据库配置更改为新的基于文档的 MongoDB 数据库有多困难?出乎意料的是,当我们拥有正确的工具时,这相对容易。

幸运的是,一些聪明的人创建了 Djongo,这是一个用于连接到 MongoDB 数据库的 Django 应用程序的数据库映射器。

Djongo 使您能够将 MongoDB 用作 Django 项目的后端数据库,而无需更改 Django 对象关系映射 (ORM)。Djongo 仅将 SQL 查询字符串转换为 MongoDB 查询文档,从而大大简化了用 MongoDB 替换 RDBMS 的过程。因此,所有 Django 功能、模型和其他组件都能按原样工作。

与传统的 Django ORM 相比,Djongo 使您能够快速开发和演进您的应用程序模型。由于 MongoDB 是一个无模式数据库,因此 MongoDB 不要求您在每次重新定义模型时都重新定义模式。

此外,使用 Djongo,您不再需要数据库迁移。只需在数据库配置中定义 `ENFORCE_SCHEMA`: False。Djongo 会为开发人员透明地管理集合,因为它知道如何隐式发出 PyMongo 命令来创建 MongoDB 集合。

确保您正在虚拟环境中运行,并使用以下命令安装 Djongo:

(.venv) > pip install djongo

现在回到 Azure 门户,点击 连接字符串 菜单,并从您的帐户中复制这四个字段的内容:主机端口用户名主密码

接下来,编辑 `\conduit\settings.py` 文件,并将 `DATABASES` 常量替换为以下设置:

DATABASES = {
    'default': {
        'ENGINE': 'djongo',
        'ENFORCE_SCHEMA': False,
        'NAME': 'conduit_db',
        'CLIENT': {
            'host': '<<YOUR-ACCOUNT-HOST>>',
            'port': 10255,
            'username': '<<YOUR-ACCOUNT-USERNAME>>,
            'password': ' <<YOUR-ACCOUNT-PASSWORD>> ',
            'authMechanism': 'SCRAM-SHA-1',
            'ssl': True,
            'tlsAllowInvalidCertificates': True,
            'retryWrites': False
        }   
    }   
}

然后修改 `CORS_ORIGIN_WHITELIST` 常量,将 `http` 方案包含在 `localhost` 地址中:

CORS_ORIGIN_WHITELIST = (
    'http://0.0.0.0:4000',
    'https://:4000',
    'https://:8080'
)

  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying authentication.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying profiles.0001_initial... OK
  Applying articles.0001_initial... OK
  Applying articles.0002_comment... OK
  Applying articles.0003_auto_20160828_1656... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying profiles.0002_profile_follows... OK
  Applying profiles.0003_profile_favorites... OK
  Applying sessions.0001_initial... OK

将数据从 Azure Database for PostgreSQL 导出到 JSON 文件

我们可以只创建一个空的 MongoDB 数据库并开始工作,而无需任何数据。但是,请记住,我们在多个文章中一直在使用同一个 PostgreSQL 数据库,并且我们不想丢失这些数据。在现实世界中,您需要帮助将这些数据从 PostgreSQL 数据库迁移到 Mongo DB 数据库。现在,我们一步一步地这样做,但规模较小。

打开 Visual Studio Code,点击 扩展 选项卡,然后搜索 PostgreSQL。安装 Microsoft 的 VS Code PostgreSQL 扩展。

安装 PostgreSQL 扩展后,您将能够连接到您的 Azure Database for PostgreSQL 实例,对数据库运行查询,并将结果另存为 JSON、CSV 或 Excel。

现在,打开您的项目文件,创建一个名为 `PostgreSQLCSV` 的新文件夹,然后创建以下 SQL 文件并包含相应的内容:

PostgreSQLCSV\articles_tag.sql

SELECT
id as "id.int32()",
to_char(created_at, 'yyyy-mm-dd HH24:MI:SS') as "created_at.date_ms(yyyy-MM-dd H:mm:ss)",
to_char(updated_at, 'yyyy-mm-dd HH24:MI:SS') as "updated_at.date_ms(yyyy-MM-dd H:mm:ss)",
tag as "tag.string()",
slug as "slug.string()"
FROM articles_tag;

PostgreSQLCSV\authentication_user.sql

SELECT
id as "id.int32()",
password as "password.string()",
is_superuser as "is_superuser.boolean()",
username as "username.string()",
email as "email.string()",
is_active as "is_active.boolean()",
is_staff as "is_staff.boolean()",
to_char(created_at, 'yyyy-mm-dd HH24:MI:SS') as "created_at.date_ms(yyyy-MM-dd H:mm:ss)",
to_char(updated_at, 'yyyy-mm-dd HH24:MI:SS') as "updated_at.date_ms(yyyy-MM-dd H:mm:ss)"
FROM authentication_user;

PostgreSQLCSV\profiles_profile.sql

SELECT
id as "id.int32()",
to_char(created_at, 'yyyy-mm-dd HH24:MI:SS') as "created_at.date_ms(yyyy-MM-dd H:mm:ss)",
to_char(updated_at, 'yyyy-mm-dd HH24:MI:SS') as "updated_at.date_ms(yyyy-MM-dd H:mm:ss)",
bio as "bio.string()",
image as "image.string()",
user_id as "user_id.int32()"
FROM profiles_profile;

PostgreSQLCSV\articles_article.sql

>SELECT
id as "id.int32()",
to_char(created_at, 'yyyy-mm-dd HH24:MI:SS') as "created_at.date_ms(yyyy-MM-dd H:mm:ss)",
to_char(updated_at, 'yyyy-mm-dd HH24:MI:SS') as "updated_at.date_ms(yyyy-MM-dd H:mm:ss)",
slug as "slug.string()",
title as "title.string()",
description as "description.string()",
body as "body.string()",
author_id as "author_id.int32()"
FROM articles_article;

PostgreSQLCSV\articles_article_tags.sql

SELECT
id as "id.int32()",
article_id as "article_id.int32()",
tag_id as "tag_id.int32()"
FROM articles_article_tags;

PostgreSQLCSV\articles_comment.sql

SELECT
id as "id.int32()",
to_char(created_at, 'yyyy-mm-dd HH24:MI:SS') as "created_at.date_ms(yyyy-MM-dd H:mm:ss)",
to_char(updated_at, 'yyyy-mm-dd HH24:MI:SS') as "updated_at.date_ms(yyyy-MM-dd H:mm:ss)",
body as "body.string()",
article_id as "article_id.int32()",
author_id as "author_id.int32()"
FROM articles_comment;

每个查询都针对我们 PostgreSQL 数据库中的特定表。请注意,列名还包括数据类型。这种命名格式稍后会很有帮助,因为我们可以向 MongoDB 导入工具提供这些数据类型。

我们将使用 VS Code 的 PostgreSQL 扩展运行上面每个查询。对每个 SQL 查询执行以下四个步骤:

  1. 在 `PostgreSQLCSV` 文件夹中找到并选择 SQL 查询文件。

  2. 在中央面板中打开 SQL 文件,双击查询,然后点击 执行查询 菜单。

  3. 您会注意到一个右侧窗口显示了结果表。右键单击表中的一个单元格,然后点击 另存为 CSV 菜单选项。

  4. 最后,将文件保存为与查询相同的名称,将 SQL 扩展名替换为 CSV(例如,`articles_tag.sql` 变为 `articles_tag.csv`)。将结果文件保存在同一个 `PostgreSQLCSV` 文件夹中。

在 `articles_tag` 集合上创建复合索引

我们 Conduit Django 应用程序中的一些查询(例如 `articles_tag` 集合)在对该集合中的多个字段使用 `Order By` 子句。在创建涵盖这些字段的单个复合索引之前,我们的应用程序将无法执行此类查询。

因此,请转到您的 Conduit Cosmos DB 帐户,然后点击左侧面板上的 快速入门 菜单项。然后,转到 MongoDB Shell 选项卡,并复制 使用 MongoDB Shell 连接 下方的行。

现在将该行粘贴到您的终端并运行它。

> mongo.exe <<YOUR-COSMOSDB-HOST>>:10255 -u <<YOUR-COSMOSDB-USER>> 
-p <<YOUR-COSMOSDB-PASSWORD>> --ssl --sslAllowInvalidCertificates

接下来,运行 `show databases` 命令。

globaldb:PRIMARY> show databases
conduit_db  0.000GB

然后选择 `conduit_db` 数据库。

globaldb:PRIMARY> use conduit_db
switched to db conduit_db

在 `articles_tag` 集合上创建一个覆盖 `created_at` 和 `updated_at` 字段的复合索引。

globaldb:PRIMARY> db.articles_tag.createIndex({created_at:1,updated_at:1})
{
        "createdCollectionAutomatically" : false,
        "numIndexesBefore" : 3,
        "numIndexesAfter" : 4,
        "ok" : 1
}

将 JSON 文件导入 Cosmos DB MongoDB 数据库

现在是时候将之前创建的 CSV 文件从 PostgreSQL 导入到 Mongo DB 集合中了。首先,找到并安装适合您系统的 MongoDB 数据库工具

接下来,运行 `mongoimport` 命令行工具将 CSV 文件转换为您 Cosmos DB 帐户下的 MongoDB 文档。请注意,您必须为以下六个文件中的每一个运行 `mongoimport`:

articles_tag.csv

mongoimport --host <<YOUR-COSMOSDB-HOST>>:10255 -u <<YOUR-COSMOSDB-USER>> 
-p <<YOUR-COSMOSDB-PASSWORD>> --db conduit_db --collection articles_tag --ssl --type csv 
--headerline --columnsHaveTypes --file PostgreSQLCSV\articles_tag.csv 
--writeConcern="{w:0}"

authentication_user.csv

mongoimport --host <<YOUR-COSMOSDB-HOST>>:10255 -u <<YOUR-COSMOSDB-USER>> 
-p <<YOUR-COSMOSDB-PASSWORD>> --db conduit_db --collection authentication_user 
--ssl --type csv --headerline --columnsHaveTypes 
--file PostgreSQLCSV\authentication_user.csv --writeConcern="{w:0}"

profiles_profile.csv

mongoimport --host <<YOUR-COSMOSDB-HOST>>:10255 -u <<YOUR-COSMOSDB-USER>> 
-p <<YOUR-COSMOSDB-PASSWORD>> --db conduit_db --collection profiles_profile 
--ssl --type csv --headerline --columnsHaveTypes 
--file PostgreSQLCSV\profiles_profile.csv --writeConcern="{w:0}"

articles_article.csv

mongoimport --host <<YOUR-COSMOSDB-HOST>>:10255 -u <<YOUR-COSMOSDB-USER>> 
-p <<YOUR-COSMOSDB-PASSWORD>> --db conduit_db --collection articles_article 
--ssl --type csv --headerline --columnsHaveTypes 
--file PostgreSQLCSV\articles_article.csv --writeConcern="{w:0}"

articles_comment.csv

mongoimport --host <<YOUR-COSMOSDB-HOST>>:10255 -u <<YOUR-COSMOSDB-USER>> 
-p <<YOUR-COSMOSDB-PASSWORD>> --db conduit_db --collection articles_comment 
--ssl --type csv --headerline --columnsHaveTypes 
--file PostgreSQLCSV\articles_comment.csv --writeConcern="{w:0}"

articles_article_tags.csv

mongoimport --host <<YOUR-COSMOSDB-HOST>>:10255 -u <<YOUR-COSMOSDB-USER>> 
-p <<YOUR-COSMOSDB-PASSWORD>> --db conduit_db --collection articles_article_tags 
--ssl --type csv --headerline --columnsHaveTypes 
--file PostgreSQLCSV\articles_article_tags.csv --writeConcern="{w:0}"

本地运行 Python 应用程序

打开您的终端。然后在您的虚拟环境中运行此命令:

(.venv) PS > python manage.py runserver 

Django version 3.1.4, using settings 'conduit.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.

现在打开您的浏览器。转到 `http://127.0.0.1:8000/api/articles`,检查来自托管在您的 Cosmos DB 帐户中的 MongoDB 数据库的文章。

最后,打开 `http://127.0.0.1:8000/api/tags` 获取标签列表。

后续步骤

在本文中,我们修改了我们的 Python 应用程序,使其能够访问我们新的 Azure Cosmos DB 数据库中的 MongoDB 安装。

我们首先创建了一个新的 Azure Cosmos DB API for MongoDB。然后我们安装了 Djongo Mapper,它通过将 Python 对象映射到 MongoDB 文档来克服 PyMongo 编程的常见陷阱。Djongo 使您能够无缝替换您的关​​联数据库,通过调整您应用程序的数据库配置,将 MongoDB 文档映射到 Python 对象。

到目前为止,我们已经探索了如何通过将数据和代码迁移到云来现代化应用程序。在本系列的最后一篇文章中,我们将讨论如何开始使应用程序更具云原生性。我们将演示如何开始将旧应用程序的功能迁移到基于 Azure 函数的微服务中。我们将选择应用程序中的一些现有功能,并展示如何将其迁移到用 Python 编写的 Azure 函数中。继续阅读下一篇文章 以了解如何操作。

要了解有关如何在云中构建和部署 Python 应用程序的更多信息,请查看 Python 应用开发 - Azure 上的 Python

© . All rights reserved.