选择在其他记录列表中找不到的记录
Selecting records not found in other list of records
场景
玩家参加活动。如果他们要参加活动,他们应该提供信息。
待解决的问题
我想 select 尚未提供信息的玩家,如果他们计划参加特定活动。
你的目标
作为所用技术的初学者,非常感谢您对我在下面建议的解决方案进行改进的验证和建议。
解决方案
技术: python、postgreSQL 和 Pony ORM
Pony ORM 中的实体模型:
class Event(db.Entity):
_table_ = "event"
start = Required(date)
players = Set("Attendance")
class Player(db.Entity):
_table_ = "player"
first_name = Optional(str)
last_name = Required(str)
phone_number = Required(str)
email = Required(str)
events = Set("Attendance")
class Attendance(db.Entity):
_table_ = "attendance"
event = Required(Event)
player = Required(Player)
status = Required(bool)
PrimaryKey(event, player)
想法:
- 获取提供信息的玩家列表(如果他们参加活动)
- 获取不在 1 创建的列表中的玩家列表。
想法的当前实现:
players = select(p for p in Player if p not in select(p for p in Player
for a in Attendance if p == a.player and a.event == next_event))
可以重构您的查询以使其更简单。首先,我们可以将内部查询中 Player
和 Attendance
的显式连接替换为通过属性访问的隐式连接:
select(p for p in Player if p not in select(p for p in Player
for attendance in p.events if attendance.event == next_event))
为了进一步简化查询,我们可以通过编写表达式 p.events.event
:
来使用 attribute lifting
select(p for p in Player if p not in select(
p for p in Player if next_event in p.events.event))
p.events
表达式 returns 一组 Attendance
记录。在 Pony 中,当你有一个集合实例时,这个集合拥有它的项目的所有属性,当你访问这个属性时,你将得到一组对应项目属性的所有值。表达式 p.events.event
的值将是与特定玩家链接的所有 Event
个对象的集合。
简化查询的下一步是将生成器替换为 lambda。这样查询看起来会更短一些:
Player.select(lambda p: p not in Player.select(
lambda p: next_event in p.events.event))
但如果我们意识到内部查询是不必要的并将查询重写为:
,则可以实现最大的简化
Player.select(lambda p: next_event not in p.events.event)
我认为这是使用 PonyORM 编写此查询的最简洁的方式
场景
玩家参加活动。如果他们要参加活动,他们应该提供信息。
待解决的问题
我想 select 尚未提供信息的玩家,如果他们计划参加特定活动。
你的目标
作为所用技术的初学者,非常感谢您对我在下面建议的解决方案进行改进的验证和建议。
解决方案
技术: python、postgreSQL 和 Pony ORM
Pony ORM 中的实体模型:
class Event(db.Entity):
_table_ = "event"
start = Required(date)
players = Set("Attendance")
class Player(db.Entity):
_table_ = "player"
first_name = Optional(str)
last_name = Required(str)
phone_number = Required(str)
email = Required(str)
events = Set("Attendance")
class Attendance(db.Entity):
_table_ = "attendance"
event = Required(Event)
player = Required(Player)
status = Required(bool)
PrimaryKey(event, player)
想法:
- 获取提供信息的玩家列表(如果他们参加活动)
- 获取不在 1 创建的列表中的玩家列表。
想法的当前实现:
players = select(p for p in Player if p not in select(p for p in Player
for a in Attendance if p == a.player and a.event == next_event))
可以重构您的查询以使其更简单。首先,我们可以将内部查询中 Player
和 Attendance
的显式连接替换为通过属性访问的隐式连接:
select(p for p in Player if p not in select(p for p in Player
for attendance in p.events if attendance.event == next_event))
为了进一步简化查询,我们可以通过编写表达式 p.events.event
:
select(p for p in Player if p not in select(
p for p in Player if next_event in p.events.event))
p.events
表达式 returns 一组 Attendance
记录。在 Pony 中,当你有一个集合实例时,这个集合拥有它的项目的所有属性,当你访问这个属性时,你将得到一组对应项目属性的所有值。表达式 p.events.event
的值将是与特定玩家链接的所有 Event
个对象的集合。
简化查询的下一步是将生成器替换为 lambda。这样查询看起来会更短一些:
Player.select(lambda p: p not in Player.select(
lambda p: next_event in p.events.event))
但如果我们意识到内部查询是不必要的并将查询重写为:
,则可以实现最大的简化Player.select(lambda p: next_event not in p.events.event)
我认为这是使用 PonyORM 编写此查询的最简洁的方式