1行のコードを追加するだけでMongoDBでDjangoを使用する方法。

1行のコードを追加するだけでMongoDBでDjangoを使用する方法。

DjangoプロジェクトのバックエンドデータベースとしてMongoDBを使用するには、次の1行をsettings.pyファイルに追加するだけです。

DATABASES = { ‘default’: { ‘ENGINE’: ‘djongo’, ‘NAME’: ‘your-db-name’, }}

とても簡単です!

次に、管理者ホーム(localhost:8000 / admin /)にログインし、管理GUIを使用して「埋め込みドキュメント」をMongoDBに追加し始めます。

2017年10月、MongoDBは公開の最終ステップを完了し、IPOの価格を24ドルに設定し、その過程で1億9,200万ドルを調達しました。会社の財政は着実に成長しています:

MongoDBは、オープンソースのデータベースソフトウェアを提供します。これは、厳しい予算に制約されながら立ち上げようとしている初期段階のスタートアップにとって非常に役立ちます。MongoDBのGoogle検索トレンドを確認したところ、関心が着実に高まっていることがわかりました。

MongoDBは、使用するデータベースソフトウェアとしてますます人気が高まっています。データベースとデータベース管理システム(DBMS)は、50年以上前から存在しています。それらは1960年代初頭に登場し、最も人気のあるフレーバーはリレーショナルデータベースシステムでした。

しかし、MongoDBはそれ自体を「非リレーショナル」データベースシステムと呼んでおり、データを保存するアプローチについて高い主張をしています。それで、ここでの大きな取引は正確には何ですか?

MongoDBとSQL

ほとんどすべてのリレーショナルデータベースシステムは、構造化照会言語(SQL)(またはその微調整バージョン)を使用してデータ管理ソフトウェアと通信します。いくつかの大学のコースは、SQL構文の理解と習得に専念しています。

SQLは、プロプライエタリまたはオープンソースのデータベース(DB)ソフトウェアを操作するための事実上の言語になりました。その後、MongoDBが登場し、この古代の権力言語を完全に無視することを決定し、独自のクエリ構文を導入しました。

言語は私がここで発声しないモルドールの言語です。共通の言葉で、それは言います、「それらすべてを支配する一つの指輪。それらを見つけるための一つの指輪。それらすべてを運び、暗闇の中でそれらを束縛するための一つの指輪。」-ガンダルフ(指輪物語から

MongoDBスキーマレスとSQLスキーマ: SQLデータベースでは、スキーマと呼ばれるものでテーブルとフィールドタイプを定義するまで、データを追加することはできません。MongoDBデータベースでは、いつでもどこでもデータを追加できます。ドキュメントのデザインやコレクションを事前に指定する必要はありません。

MongoDBドキュメントとSQLテーブル: SQLデータベースは、関連するデータテーブルのストアを提供します。すべての行は異なるレコードです。設計は厳格です。同じテーブルを使用して異なる情報を格納したり、数値が必要な場所に文字列を挿入したりすることはできません。

MongoDBデータベースには、JSONのようなフィールドと値のペアのドキュメントが格納されます。同様のドキュメントをコレクションに格納できます。これは、SQLテーブルに類似しています。ただし、好きなデータを任意のドキュメントに保存できます—MongoDBは文句を言いません。SQLテーブルは厳密なデータテンプレートを作成するため、間違いを犯しにくいです。MongoDBはより柔軟で寛容ですが、どこにでもデータを保存できると、一貫性の問題が発生する可能性があります。

MongoDBはSQLのスーパーセットではないと主張するオンラインコンテンツが多数あります。SQLで実行されるアプリケーションはMongoDBに移植できません。私はここで、Djangoのコンテキストでは、MongoDBがSQLのスーパーセットであると主張します

では、MongoDBはSQLのスーパーセットではないという一般的な信念が、そもそも存在するのはなぜですか?

MongoDBではデータの非正規化が必要です: MongoDbではJOINサポートはありません。これは、ドキュメントを非正規化する必要があることを意味します。非正規化されたドキュメントはクエリを高速化しますが、複数の非正規化されたドキュメントのドキュメントフィールド情報の更新は大幅に遅くなります。

JOINはありません。SQLクエリは強力なJOIN句を提供します。1つのSQLステートメントを使用して、複数のテーブルの関連データを取得できます。MongoDBのような非リレーショナルデータベースには、リレーショナルデータベースのようなJOINはありません。つまり、複数のクエリを実行し、コード内でデータを手動で結合する必要があります。

トランザクションなし: SQLデータベースでは、トランザクションで2つ以上の更新を実行できます。これは、成功または失敗を保証するオールオアナッシングラッパーです。2つの更新を個別に実行すると、1つは成功し、もう1つは失敗する可能性があるため、数値が同期しなくなります。トランザクション内に同じ更新を配置すると、両方が成功するか、両方が失敗することが保証されます。

外部キー制約なし:ほとんどのSQLデータベースでは、外部キー制約を使用してデータ整合性ルールを適用できます。これにより、すべての行に、結合テーブルの1つのエントリに一致するコードの有効な外部キーがあり、1つ以上の行がまだそれらを参照している場合に、結合テーブルのレコードが削除されないようにします。

スキーマは、データベースが従うようにこれらのルールを適用します。開発者またはユーザーがレコードを追加、編集、または削除することはできません。その結果、無効なデータまたは孤立したレコードが発生する可能性があります。同じデータ整合性オプションはMongoDBでは使用できません。他のドキュメントに関係なく、必要なものを保存できます。理想的には、単一のドキュメントがアイテムに関するすべての情報の唯一のソースになります。

データベースモデルの必要性

Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects. While objects are a good way to represent data, a problem arises when we want to make the data persistent. The amount of data could be huge, and it must be retrieved from the persistent memory quickly and efficiently. This database software must be used to store the objects. A possible database software is a relational, SQL-based database software.

An object-relational mapper (ORM) is a code library that automates the transfer of data stored in relational database tables into Python objects that are used in Python code. ORMs provide a high-level abstraction upon a relational database that allows a developer to write Python code instead of SQL syntax to create, read, update and delete data and schemas in their database. Developers can use the Python programming language with which they are comfortable instead of writing SQL statements or stored procedures.

An example of an ORM framework for Python is SQLAlchemy. The SQLAlchemy ORM presents a method of associating user-defined Python classes with database tables, and instances of those classes (objects) with rows in their corresponding tables. It includes a system that transparently synchronizes all changes in state between objects and their related rows. Web frameworks like flask use SQLAlchemy for storing data persistently.

Django ORM: Django comes with its own ORM or model for short.The model is the single, definitive source of information about your data. It contains the essential fields and behaviors of the data you’re storing. Generally, each model maps to a single database table. The Django Model also make it possible to switch between various relational databases such as Oracle SQL, MySQL, or MSSQL.

Using Django ORM to add documents into MongoDB

Let’s say you want to create a blogging platform using Django with MongoDB as your backend.

In your Blog app/models.py file define the BlogContent model:

from djongo import modelsfrom djongo.models import forms
class BlogContent(models.Model): comment = models.CharField(max_length=100) author = models.CharField(max_length=100) class Meta: abstract = True

To access the model using Django Admin, you will need a Form definition for the above model. Define it as shown below:

class BlogContentForm(forms.ModelForm): class Meta: model = BlogContent fields = ( 'comment', 'author' )

Now “embed” your BlogContent inside a BlogPost using the EmbeddedModelField as below:

class BlogPost(models.Model): h1 = models.CharField(max_length=100) content = models.EmbeddedModelField( model_container=BlogContent, model_form=BlogContentForm ) 

That’s it you are set! Fire up Django Admin on localhost:8000/admin/ and this is what you get:

Next, assume you want to “extend” the author field to contain more than just the name. You need both a name and email. Simply make the author field an “embedded” field instead of a “char” field:

class Author(models.Model): name = models.CharField(max_length=100) email = models.CharField(max_length=100) class Meta: abstract = Trueclass AuthorForm(forms.ModelForm): class Meta: model = Author fields = ( 'name', 'email' )
class BlogContent(models.Model): comment = models.CharField(max_length=100) author = models.EmbeddedModelField( model_container=Author, model_form=AuthorForm ) class Meta: abstract = True

If a blog post has multiple content from multiple authors, define a new model:

class MultipleBlogPosts(models.Model): h1 = models.CharField(max_length=100) content = models.ArrayModelField( model_container=BlogContent, model_form=BlogContentForm )

Fire up Django Admin with the new changes and you have:

Ways to integrate Django and MongoDB.

The Django ORM consists of multiple Abstraction Layers stacked on top of each other.

As a web developer, you can take up the challenge of connecting Django to MongoDB in two ways. Take a look at the Django framework stack above to guess the possible entry points.

Use a MongoDB compatible model

You can completely avoid using the “batteries included” Django models in your project. Instead, use a third party framework like MongoEngine or Ming in you Django projects.

Choosing a different Model means you miss out on:

  • 1500+ core contributors to the project
  • Hourly fixes and ticket resolution

You’d ramp down on the expertise of existing Django models and ramp up on the new model framework. But perhaps the biggest drawback is that your project can’t use any of Django’s contrib models! Forget about using Admin, Sessions, Users, Auth, and other contrib modules for your project.

Some of these disadvantages are offset by forking a new branch of Django itself. Django-nonrel is an independent branch of Django that adds NoSQL database support to Django. Django-nonrel allows for writing portable Django apps. However, the admin interface does not work fully. There is no active development taking place on the Django-nonrel project.

Django MongoDB Engine is another MongoDB backend for Django which is a fork off the MongoEngine ODM.

Django SQL to MongoDB transpiler — Djongo

Another approach is to translate Django SQL query syntax generated by the Django ORM into pymongo commands. Djongo is one such SQL to MongoDB query compiler. It translates every SQL query string into a mongoDB query document. As a result, all Django models and related modules work as is. With this approach, you gain on:

  • Reuse of Django Models: Django is a stable framework with continuous development and enhancements. The Django ORM is quite extensive and feature-rich. Defining a third party ORM to work with MongoDB means reproducing the entire Django ORM again. The new ORM needs to constantly align with the Django ORM. Several Django features will never make it into the third party ORM. The idea with Djongo is to reuse existing Django ORM features by finally translating SQL queries to MongoDB syntax.
  • SQL syntax will never change regardless of future additions to Django. By using Djongo, your project is now future proof!

Making Django work with MongoDB

Emulating Schema in MongoDB: While there is no schema support in MongoDB, this can be emulated. Djongo provides the schema support required in Django by using and defining a combination of MongoDB validator rules and by creating a __schema__ collection. The __schema__ collection stores information for supporting features like the SQL AUTOINCREMENT key.

JOIN support in MongoDB: In version 3.2, MongoDB introduced the $lookup operator. It performs a left outer join to a collection in the same database to filter in documents from the “joined” collection for processing. The $lookup stage does an equality match between a field from the input documents with a field from the documents of the “joined” collection.

To each input document, the $lookup stage adds a new array field whose elements are the matching documents from the “joined” collection. The $lookup stage passes these reshaped documents to the next stage.

Djongo uses the $lookup aggregation operator to perform all Django related JOIN queries. This is how it makes admin and other contrib modules work as is.

Transaction support in MongoDB: Despite the power of single-document atomic operations, there are cases that require multi-document transactions. When executing a transaction composed of sequential operations, certain issues arise, wherein if one operation fails, the previous operation within the transaction must “rollback” to the previous state — that is, the “all or nothing.”

For situations that require multi-document transactions, Djongo implements the two-phase commit pattern to provide support for these kinds of multi-document updates. Using two-phase commit ensures that data is consistent and, in case of an error, the state that preceded the transaction is recoverable.

Djongo comes with its own set of compromises, though. So what are the disadvantages of opting to use Djongo for your Django project?

Performance: The Django ORM does the heavy lifting of converting complex object manipulations to standard SQL query strings. If your backend database was SQL-based, you could pass this query string directly to it with almost no post-processing. With Djongo, however, the query string will now have to be converted into a MongoDB query document.

This is going to require some CPU cycles. But if extra CPU cycles are really such a problem, you probably shouldn’t be using Python in the first place.

Conclusion

I took you through several ways of integrating Django with MongoDB. You will find a multitude of online literature describing the MongoEngine and other variants for doing this.

I focused on Djongo which is a new connector that makes this possible in a different way. It is easy to use and makes the process of migrating from a SQL backend to MongoDB very simple, by adding just one line of code.