関係
現在、ormarは2種類の関係をサポートしています:
- foreignkeyフィールドを持つ1対多(および1対多)
- ManyTomanyフィールドを持つ多対多
以下に、各リレーションシップの非常に基本的な定義例を見つけることができます。
メソッド、可能性、定義などの詳細については、ドキュメントの次のセクションをお読みください。
外部キー
複数対1のリレーションシップを定義するには、外部キーフィールドを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 | from typing import Dict, Optional, Union
import databases
import ormar
import sqlalchemy
DATABASE_URL = "sqlite:///test.db"
ormar_base_config = ormar.OrmarConfig(
database=databases.Database(DATABASE_URL), metadata=sqlalchemy.MetaData()
)
class Department(ormar.Model):
ormar_config = ormar_base_config.copy()
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
class Course(ormar.Model):
ormar_config = ormar_base_config.copy()
id: int = ormar.Integer(primary_key=True)
name: str = ormar.String(max_length=100)
department: Optional[Union[Department, Dict]] = ormar.ForeignKey(Department)
|
!!!ヒント1対多のリレーションシップの詳細については、外部キーセクションを参照してください
逆外部キー
1対多の関係の定義も自動的に登録してくれるForeignKeyを使っています。
したがって、上記の例では。
| class Department(ormar. Model):
base_or_config. copy()
id: int=ormar.Integer(プライマリキー=True)
name: str=ormar.String(max_length=100)
#以下のような仮想フィールドがあります。
コース:オプション[リスト[コース]]=ormar. ForeignKey(コース、仮想=True)
自分で定義するのではなく、ormarが自分のために定義することに注意してください。
|
!!!ヒント複数対1のリレーションシップ(つまり、生成されたフィールドの名前の変更)の詳細については、外部キーセクションにアクセスしてください
!!!tip ReverseforeignKeyを使用すると、queryset-proxyを使用して関連するモデルをクエリできます。
| `await department.courses.all()` を使用して、特定の部門などにのみ関連するデータを取得できます。
|
多対多
多対多のリレーションシップを定義するには、ManyTomanyフィールドを使用します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 | class Category(ormar. Model):
ormar_config=ormar. OrmarConfig
データベース=データベース、
metadata=メタデータ,
tablename="カテゴリ",
)
id: int=ormar.Integer(プライマリキー=True)
name: str=ormar.String(max_length=40)
class Post(ormar. Model):
ormar_config=ormar. OrmarConfig
データベース=データベース、
metadata=メタデータ,
)
id: int=ormar.Integer(プライマリキー=True)
title: str=ormar.String(max_length=200)
カテゴリ:オプション[リスト[カテゴリ]]=ormar. ManyTomany(カテゴリ)
|
!!!ヒント多対多の関係の詳細については、多対多のセクションを参照してください
!!!tip ManyTomanyを使用すると、queryset-proxyを使用して関連するモデルをクエリできます。
| `await post.categories.all()` だけでなく、`await category.posts.all()` を使用して、特定の投稿、カテゴリなどにのみ関連するデータを取得することができます。
|
フィールドを通して
ManyTomanyリレーションシップの一部として、フィルタリング、ソートなどに使用できる他のフィールドを含むパススルーモデルを定義できます。このように定義されたフィールドは、m2 mモデルの現在のクエリの反対側で公開されます。
したがって、モデルAからモデルBにクエリを実行すると、モデルBだけがthroughフィールドを公開します。関連する各モデルの一方通行のモデル/フィールドであるため、どちらが意味を持ちます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 | class Category(ormar. Model):
ormar_config=ormar. OrmarConfig
データベース=データベース、
metadata=メタデータ,
tablename="カテゴリ",
)
id=ormar. Integer(プライマリキー=True)
name=ormar. String(max_length=40)
#スルーモデルに追加のフィールドを指定することができます。
class Post Category(ormar. Model):
ormar_config=ormar. OrmarConfig
データベース=データベース、
metadata=メタデータ,
tablename="post_x_カテゴリ",
)
id: int=ormar.Integer(プライマリキー=True)
sort_order: int=ormar.Integer(nullable=True)
param_name: str=ormar.String(default="Name",max_length=200)
class Post(ormar. Model):
ormar_config=ormar. OrmarConfig
データベース=データベース、
metadata=メタデータ,
)
id: int=ormar.Integer(プライマリキー=True)
title: str=ormar.String(max_length=200)
カテゴリー=ormar. ManyTomany(カテゴリー、through=PostCategory)
|
!!!ヒント多対多のリレーションシップとフィールドの詳細については、多対多のセクションにアクセスしてください
!!!tip ManyTomanyを使用すると、queryset-proxyを使用して関連するモデルをクエリできます。
| `await post.categories.all()` だけでなく、`await category.posts.all()` を使用して、特定の投稿、カテゴリなどにのみ関連するデータを取得することができます。
|
リレーションシップのデフォルトのソート順
デフォルトでは、リレーションシップはモデルのデフォルトのソート順序に従います。
!!!ヒントモデルの並べ替え順序の詳細については、ドキュメントのモデルセクションを参照してください
ただし、order_byパラメーターと関連_order_byパラメーターをリレーショナルに指定することで、クエリ中に関連するモデルがロードされる順序を変更できます。
リレーションシップでは、直接関連するモデル列、または複数対複数の列の場合はモデル列でのみソートできます {through_field_name}__{column_name}
構成例を次に示します。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | データベース=データベース。データベース(DATABASE_URL)
Metadata=sqlalchemy. MetaData()
base_ormar_config=ormar. OrmarConfig(ベースの設定
データベース=データベース、
metadata=メタデータ,
)
class Author(ormar. Model):
base_or_config. copy()
id: int=ormar.Integer(プライマリキー=True)
name: str=ormar.String(max_length=100)
class Book(ormar. Model):
base_or_config. copy()
id: int=ormar.Integer(プライマリキー=True)
著者:オプション[著者]=ormar. ForeignKey(
著者、order_by=["name"]、関連するorder_by=["-year"]
)
title: str=ormar.String(max_length=100)
year: int=ormar.Integer(nullable=True)
ランキング: int=ormar.Integer(nullable=True)
|
今すぐ呼び出す:
await Author.objects.select_related("books").get() -書籍は書籍の年の降順で並べ替えられます
await Book.objects.select_related("author").all() -著者は著者名の昇順でソートされます
自己参照と遅延参照
自動リレーションシップを作成するか、少なくとも2つの異なるリレーションシップで互いに参照する2つのモデルを作成するには(裏面が自動的に登録されることに注意してください)、入力モジュールでForwardRefを使用する必要があります。
1
2
3
4
5
6
7
8
9
10
11
12 | PersonRef=ForwardRef("人")
class Person(ormar. Model):
base_or_config. copy()
id: int=ormar.Integer(プライマリキー=True)
name: str=ormar.String(max_length=100)
スーパーバイザー: PersonRef=ormar.ForeignKey(PersonRef、関連する名前="従業員")
Person. update_forward_refs()
|
!!!ヒント自己参照と後回しの関係の詳細については、後回しのコメントセクションをご覧ください