Простите меня, если это очевидный вопрос, но я новичок в пони и базах данных в целом и не нашел нужной части документации, отвечающей на этот вопрос.
Я пытаюсь создать базу данных с компаниями и местами, где у этих компаний есть офисы. Это отношение «многие ко многим», поскольку каждая компания находится в нескольких местах, и каждое место может быть хостом для нескольких компаний. Я определяю свои сущности как таковые:
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')
В идеале я хотел бы иметь возможность написать функцию, которая добавляет компанию в базу данных, а также добавляет список местоположений, где эта компания существует, а также обязательно добавляет новые экземпляры местоположения, если они еще не существуют. Я могу быстро придумать два способа сделать это.
Во-первых, нужно попытаться войти в местоположение, даже если оно существует, и обработать исключение:
@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)
Во-вторых, запросить базу данных и узнать, существуют ли еще местоположения:
@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)
Из этих двух я предполагаю, что более питонический способ сделать это — просто обработать исключение, но не приведет ли это к проблеме N + 1? Я заметил, что, используя имя в качестве первичного ключа, я делаю запрос каждый раз, когда обращаюсь к объекту с помощью индекса. Когда я просто позволяю пони выбирать последовательные идентификаторы, мне не нужно запрашивать. Я еще не тестировал это с какими-либо большими наборами данных, поэтому я еще не сравнивал.