これが明らかな質問である場合は申し訳ありませんが、ポニーとデータベース全般に不慣れで、この質問に答えるドキュメントの適切な部分が見つかりませんでした。
企業とその企業がオフィスを構える場所のデータベースを作成しようとしています。各会社は複数の場所にあり、各場所は複数の会社のホストになる可能性があるため、これは多対多の関係です。私は自分のエンティティを次のように定義しています:
from pony import orm
class Company(db.Entity):
'''A company entry in database'''
name = orm.PrimaryKey(str)
locations = orm.Set('Location')
class Location(db.Entity):
'''A location for a company'''
name = orm.PrimaryKey(str)
companies = orm.Set('Company')
理想的には、会社をデータベースに追加する関数を作成し、その会社が存在する場所のリストを追加し、まだ存在しない場合は新しい場所のインスタンスを確実に追加できるようにしたいと考えています。そのための 2 つの方法をすぐに思いつくことができます。
最初に、場所が存在する場合でもその場所を入力して、例外を処理しようとします。
@orm.db_session
def add_company(name, locations):
loc_entities = []
for l in locations:
try:
loc = Location[l]
except orm.core.ObjectNotFound:
loc = Location(name=l)
else:
loc_entities.append(loc)
comp = Company(name=name, locations=loc_entities)
2 つ目は、データベースにクエリを実行し、場所がまだ存在するかどうかを確認することです。
@orm.db_session
def add_company2(name, locations):
old_loc_entities = orm.select(l for l in Location if l.name in locations)[:]
old_locations = [l.name for l in old_loc_entities]
new_locations = set(locations) - (set(locations) & set(old_locations))
loc_entities = [Location(name=l) for l in new_locations] + old_loc_entities
comp = Company(name=name, locations=loc_entities)
これら2つのうち、よりpythonicな方法は単に例外を処理することだと思いますが、これはN + 1の問題に遭遇しますか? 名前を主キーとして使用することで、インデックスを使用してエンティティにアクセスするたびにクエリを作成していることに気付きました。ポニーにシーケンシャル ID を選択させるだけでは、クエリを実行する必要はないようです。大規模なデータセットでこれをまだテストしていないため、まだベンチマークしていません。