メインコンテンツにスキップ
ブログデータベースDjango が SQL のために重い荷物を運ぶ方法

Django が SQL のためにどのように重い荷物を運ぶか

Djangoがどのように重い荷物を運ぶか - ブログヘッダー

Pythonそして特にDjango は、より少ないコードで、より効率的なアプリケーションを構築し、高度にスケーラブルなデータベースに接続するために不可欠なものです。私は、SQL とPython を使って複雑さを抽象化し、私たちの仕事と生活を少しだけ楽にするために、モダンなアプリケーションの構築とサポートに伴う日々の摩擦を減らすことについて、あなたにお話しするためにここに来ました。

面倒なことは抜きにして、想定できることは。

  • SQLは、SQLデータベースに最適化されています
  • Python は、SQL データベースに最適化されていません

この演習はUnderstanding Databases ebookと私の新しいLinode LIVE! 教育シリーズを直接サポートします。Python と Pythonic tooling を使って、実際に SQL を書く必要なく生の SQL でコマンドを実行します。私は Django のデータモデリングを使っていますが、構文はPython の SQLAlchemy パッケージと非常によく似ています。

さっそく始めましょう!
以下は
Django のデータモデルの例です。

class BlogArticle(models.Model):
    user = models.ForeignKey(User, default=1, on_delete=models.SET_DEFAULT)
    title = models.CharField(max_length=120)
    slug = models.SlugField(blank=True, null=True)
    content = models.TextField(blank=True, null=True)
    publish_timestamp = models.DateTimeField(
        auto_now_add=False,
        auto_now=False,
        blank=True,
        null=True,
    )

という Django アプリにこのモデルが住んでいると仮定しましょう。 Articles (Django アプリは基本的に Django プロジェクトの全体を構成するコンポーネントです)。

これで2つの名前が揃ったわけです。

  • Articles (アプリ名)
  • BlogArticle (モデル名)

これらを組み合わせると、SQLのテーブル名に変換されます。

articles_blog_article

Django はこの魔法を私たちのために使ってくれます。

もし、MySQLのシェルを使っていたら、こうなります。

mysql> SHOW TABLES;
+------------------------------+
| Tables_in_cfe_django_blog_db |
+------------------------------+
| articles_blog_article        |
| auth_group                   |
| auth_group_permissions       |
| auth_permission              |
| auth_user                    |
| auth_user_groups             |
| auth_user_user_permissions   |
| django_admin_log             |
| django_content_type          |
| django_migrations            |
| django_session               |
+------------------------------+
11 rows in set (0.01 sec)

では、Django のモデルのカラムを見てみましょう。

mysql> DESCRIBE articles_blog_article;
+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| id                     | bigint       | NO   | PRI | NULL    | auto_increment |
| title                  | varchar(120) | NO   |     | NULL    |                |
| slug                   | varchar(50)  | YES  | MUL | NULL    |                |
| content                | longtext     | YES  |     | NULL    |                |
| publish_timestamp      | datetime(6)  | YES  |     | NULL    |                |
| user_id                | int          | NO   | MUL | NULL    |                |
+------------------------+--------------+------+-----+---------+----------------+
12 rows in set (0.00 sec)

基本的な設定を書くことを除けば、Django はこの MySQL データベースの SQL 作業を全てやってくれました。この時点で、 Django はあまり印象的なことは何もしていません。実際、この演習のほとんどは、Django やPython を SQL の代用品として強調するためではなく、抽象化が機能するという事実を思い起こさせるために行われたものです。

Python の台頭と摩擦の代償

最も抵抗の少ない道について、また、Python が SQL を活用する最良の方法の一つであると私が考える理由についてお話しましょう。

Python を書き、読み、実行し、出荷するのは非常に簡単です。Python" を他のプログラミングパラダイムに置き換えてみると、同じことを言うのはほとんど不可能です。JavaScriptも候補に挙がっていますが、これも常にJavaと混同されています。これらは一般論であり、常に正しいとは限りませんが、アプリを開発する際に出てくる一般的な問題であることは理解しています。

これらの一般論は、Python'の英語的な構文で物事を行うため、真実となる傾向があると思います。

SQL 文とPython や Django 文を比較してみましょう。

  • SQLです。 SELECT * from articles_blog_article;
  • Python とDjangoの2種類があります。 items = BlogArticle.objects.all()

どちらのステートメントも全く同じデータを得ることができます。しかし、Python ステートメントは、Python オブジェクトのリスト (items) は、さまざまな経験を積んだほぼすべてのPython 開発者が使用できるものです。生のSQL結果は、Python のアプリで使用する前に変換する必要があります。

フィールドの説明
このSQLのフィールドの説明を詳しく見てみると。

+------------------------+--------------+------+-----+---------+----------------+
| Field                  | Type         | Null | Key | Default | Extra          |
+------------------------+--------------+------+-----+---------+----------------+
| title                  | varchar(120) | NO   |     | NULL    |                |
+------------------------+--------------+------+-----+---------+----------------+

対して、この Django のフィールドの説明です。

title = models.CharField(max_length=120)

  • どちらが摩擦が大きいか?
  • 何が起こっているのか、どちらがわかりやすいですか?

十分な情報を提供するのはどちらか?

もし、あなたがコーダーでなく、見た varchar(120)というのは、どうでしょう?少なくとも、あなたは何が言いたいかわかると思います。 max_length=120 means.クールなのは、この2つの意味がまったく同じであることです:このフィールドは120文字以内に制限してください。

データベースへのデータ追加

Djangoで。

BlogArticle.objects.create(
    title="Hello World",
    content="Coming Soon",
    slug="hello-world",
    publish_timestamp=None,
)

SQLで。

INSERT INTO `articles_blog_article` (`user_id`, `title`, `slug`, `content`, `publish_timestamp`) 
VALUES (1, 'Hello World', 'hello-world', 'Coming Soon', NULL);

シンプルさと分かりやすさで言えば、上記の勝者は間違いなく Django とPython だと思います . title = "Hello World" は、SQLで同等のカラム(フィールド)値で何が起こっているのかを把握するよりも簡単です。間違えてはいけないのは、このSQLでの書き方は、自分が何をやっているのかを知っていれば、とても効果的だということです。

複数行の追加
Django で。

items = [
    BlogArticle(title='Hello Again 0', slug='hello-again-0', content="Coming Soon"),
    BlogArticle(title='Hello Again 1', slug='hello-again-1', content="Coming Soon"),
    BlogArticle(title='Hello Again 2', slug='hello-again-2', content="Coming Soon"),
    BlogArticle(title='Hello Again 3', slug='hello-again-3', content="Coming Soon"),
    BlogArticle(title='Hello Again 4', slug='hello-again-4', content="Coming Soon"),
]
BlogArticle.objects.bulk_create(items)

SQLで。

INSERT INTO `articles_blog_article` (`user_id`, `title`, `slug`, `content`, `publish_timestamp`) 
VALUES (1, 'Hello Again 0', 'hello-again-0', 'Coming Soon', NULL),
    (1, 'Hello Again 1', 'hello-again-1', 'Coming Soon', NULL),
    (1, 'Hello Again 2', 'hello-again-2', 'Coming Soon', NULL),
    (1, 'Hello Again 3', 'hello-again-3', 'Coming Soon', NULL),
    (1, 'Hello Again 4', 'hello-again-4', 'Coming Soon', NULL);

ここでも、Python のコードはより読みやすく、SQL のコードは実際のデータについてより深い洞察を与えてくれます。そしてまた、Python は、上の Django のコードを使って、この SQL コードを私たちのために書いてくれているのです。かなりすてきでしょう?

この比較の目的は、SQLデータベースを活用する最善の方法を選ぶことではなく、生のSQLを直接書くことを学ぶためのオーバーヘッドを減らすのに役立つPython'の能力を強調することにあります。

Python パッケージがいくつかありますが、これらは基本的に生のSQLをあなたに代わって書いてくれます。

  • ジャンゴ
  • パンダ
  • SQLAlchemy
  • ポーラー
  • ダスク
  • ヴァエックス
  • Pythonの内蔵CSVモジュール
  • トータスORM
  • ポニーORM
  • SQLObject

Django が重い荷物を運ぶ
オブジェクトリレーショナルマッピングパッケージ (一般に ORM と呼ばれます) は、Python が SQL データベースを活用するための秘密のソースです。私は ORM を、任意のプログラミング言語のネイティブな構文でデータを移動するのを助ける仲 介者だと考えています。

この演習の前半で、これが Django にどのように変換されるかを見始めましたが、今度はそれを拡大しましょう。

データベースにデータがあると仮定して、次のようなコマンドを書きます。

my_post = BlogArticle.objects.first()
このステートメントは、データベースに問い合わせを行い、データを抽出し、それをPython Classという変数に代入する。 my_post.

ここから、次のようなことができるようになりました。

# using a django-managed python shell
# via python manage.py shell
>>> print(my_post.title)
Hello World

この場合、ドット表記でアクセスします。 title で宣言されたフィールドを BlogPost 前のセクションの Django モデルです。このフィールドは SQL データベーステーブルのカラムに対応します。 articles_blog_article.

ORMのおかげで、こんなことができるようになりました。

>>> my_post.title = "some other title"

このPython シェルセッションの例では my_post.title 只今 つねに 御座います "some other title".しかし、基礎となる SQL データベースは、このまったく同じデータを次のように認識します。 Hello World.データベースは、Python が最終的にコミットするまで、元のデータを保持します(別名 .save()) このデータの変更をデータベースに保存します。もしPython がこのデータをコミットしなければ、決してデータベースで更新されることはありません。これは ORM のマジックの一部分です。私たちは 使い道かわりめ を、実際の保存データに影響を与えることなく実行することができます。データベースで実際に起こっていることを変更したいときに実行します。

>>> my_post.title = "some other title again"
>>> my_post.save()

実行後 .save() のデータベースは、この特定の行について、カラムのタイトルを上記のPython の文字列と正確に一致するように更新します。ここで忘れてはならないのは .save() メソッドは、特に Django モデルでデータベースへのコミットを行うためのものです。 .save() には、実は何の意味もないのです。Python Class を継承することなく、Django のモデルクラスを形成します。

Django、MySQL、Linodeで構築する。

これは、Django があなたのために重労働をこなしてくれるという多くの例の一つです。もしあなたが、管理された MySQL データベース、CI/CD のための GitHub Actions、Terraform 、そしてAnsible と共に Linode 上で Django アプリケーションをデプロイする最新のアプローチに興味があるなら、現在 Linode で利用できる以下のコンテンツをチェックしてみてください。

Coding for EntrepreneursのGitHubには、このシリーズの各ステップに対応するコードのリポジトリがあります。また、Twitterの@JustinMitchelで状況をお知らせください。


コメント 

コメントを残す

あなたのメールアドレスは公開されません。必須項目には*印がついています。