目录
这是一个由6部分组成的系列文章的第5部分,该系列演示了如何使用Azure工具和服务逐步实现整体式Python应用程序及其数据的现代化。本文介绍如何使用Azure Cosmos DB API for MongoDB配置新的云数据库,迁移Azure Database for PostgreSQL,并将我们的应用连接到新的MongoDB数据库。
我们在这个由六部分组成的系列的前几篇文章中学习了如何将本地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会自动为所有数据编制索引,而无需架构和索引管理,从而可以轻松地将Cosmos DB与熟悉的MongoDB体验结合使用。
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”选项页上,选择“用于MongoDB的Azure Cosmos DB API”>“创建”。
API确定要创建的帐户类型。选择适用于MongoDB的Azure Cosmos DB API,因为你将创建一个数据库和一系列与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',
'http://localhost:4000',
'http://localhost: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数据库导出到JSON文件
我们可以创建一个空的MongoDB数据库,然后在没有任何数据的情况下开始工作。但是,请记住,我们已经在几篇文章中使用相同的PostgreSQL数据库,我们不想丢失这些数据。在现实世界中,您需要帮助将此数据从PostgreSQL数据库迁移到Mongo DB数据库。让我们现在一步一步地这样做,但规模较小。
打开Visual Studio Code,单击“扩展”选项卡,然后查找PostgreSQL。安装Microsoft的PostgreSQL扩展VS Code:
安装PostgreSQL扩展后,你将能够连接到适用于PostgreSQL实例的Azure数据库,对数据库运行查询,并将结果另存为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选项卡并复制Connect using 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集合中了。首先,为您的系统找到并安装Mongo DB数据库工具。
接下来,运行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安装。
我们首先为MongoDB创建了一个新的Azure Cosmos DB API。然后我们安装了Djongo Mapper,它通过将Python对象映射到MongoDB文档来克服PyMongo编程的常见陷阱。Djongo使您能够无缝替换关系数据库,通过调整应用程序的数据库配置将MongoDB文档映射到Python对象。
到目前为止,我们已经探索了如何通过将应用的数据和代码移动到云来实现应用的现代化。在本系列的最后一篇文章中,我们将讨论如何开始使应用更加云原生。我们将演示如何开始将旧应用的功能移动到基于Azure函数的微服务中。我们将从应用程序中选取一些现有功能,并演示如何将其移动到用Python编写的Azure函数中。继续阅读以下文章以了解如何操作。
若要详细了解如何在云中生成和部署Python应用,请查看Python应用开发——Azure上的Python。
https://www.codeproject.com/Articles/5330686/Modernizing-Python-Apps-and-Data-on-Azure-Part-5-D