问题描述
在sqlite的顶部使用peewee,我试图在两个没有 定义了ForeignKey关系的表之间进行左外部联接。如果右表中的项与左表中的项匹配,则可以获取数据,但是如果不匹配,则右表中的列不会将其放入返回的模型中。
class BaseModel(Model):
class Meta:
database = db
class Location(BaseModel):
location_key = CharField(primary_key=True)
lat = FloatField(null = False)
lon = FloatField(null = False)
class Household(BaseModel):
name = CharField(null=True)
location_id = CharField(null=True)
我正在尝试做类似的事情:
for h in Household.select(Household,Location).join(Location,on=(Household.location_id == Location.location_key),join_type=JOIN.LEFT_OUTER):
print(type(h),h,h.location,h.location.lat)
如果Household.location_id与“位置”中的某项匹配,则此方法有效,但是如果Household.location_id为“无”(空),那么我得到一个AttributeError: 'Household' object has no attribute 'location'
我希望可以在该位置显示,但是有效值为None。
如何在使用位置之前检查位置是否存在?我试图避免使用ForeignKey,Household.location_id和Location.location_key之间存在很多不匹配,而peewee真的很生气关于那个 ...
解决方法
我想我了解您在重新阅读后想要做什么。我建议在联接中使用Peewee的“ on”关键字参数,该参数可以将相关的Location(如果存在)修补到与“ location”不同的attr:
query = (HouseHold
.select(HouseHold,Location)
.join(Location,on=(HouseHold.location_id == Location.location_key),attr='location_obj',join_type=JOIN.LEFT_OUTER))
然后,您可以检查“ location_obj”以检索相关对象。
for house in query:
# if there was a match,get the location obj or None.
location_obj = getattr(house,'location_obj',None)
# the location_id is still present.
print(house.location_id,location_obj)
,
找到了我自己的答案。在家庭模型中实现__getattr__(self)
,如果名称为“ location”,则返回None。仅当没有具有该名称的属性时,才会调用__getattr__(self)
。