如果这是一个明显的问题,请原谅我,但我对小马和数据库一般来说是新手,并且没有找到回答这个问题的文档的正确部分。
我正在尝试创建一个包含公司以及这些公司设有办事处的位置的数据库。这是一个多对多的关系,因为每个公司位于多个位置,并且每个位置都可以托管多个公司。我这样定义我的实体:
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)
在这两个中,我猜想更 Pythonic 的方法是简单地处理异常,但这会遇到 N+1 问题吗?我注意到通过使用名称作为主键,我每次使用索引访问实体时都会进行查询。当我只是让小马选择顺序 ID 时,我似乎不需要查询。我还没有用任何大型数据集对此进行测试,所以我还没有进行基准测试。