源码:
class Action(Base): __tablename__ = 'actions' id = Column(Integer, primary_key=True) name = Column(String(50), unique=True) desc = Column(String(50), default='') ext_index = Column(String(1000)) ext_index_json = Column(Text) project_id = Column(Integer, ForeignKey('projects.id')) status = Column(Integer) create_time = Column(DateTime, default=datetime.now) update_time = Column(DateTime, default=datetime.now) state = Column(Integer(), default=1) project = relationship("Project", backref=backref("actions"))
报错:
print(project.actions.filter(Action.state>0).all())
AttributeError: 'InstrumentedList' object has no attribute 'filter'
解决方式:
project = relationship("Project", backref=backref("actions"))改成
原因:
### 懒加载: 在一对多,或者多对多的时候,如果想要获取多的这一部分的数据的时候,往往能通过一个属性就可以全部获取了。比如有一个作者,想要或者这个作者的所有文章,那么可以通过user.articles就可以获取所有的。但有时候我们不想获取所有的数据,比如只想获取这个作者今天发表的文章,那么这时候我们可以给relationship传递一个lazy='dynamic',以后通过user.articles获取到的就不是一个列表,而是一个AppenderQuery对象了。这样就可以对这个对象再进行一层过滤和排序等操作。 通过`lazy='dynamic'`,获取出来的多的那一部分的数据,就是一个`AppenderQuery`对象了。这种对象既可以添加新数据,也可以跟`Query`一样,可以再进行一层过滤。 总而言之一句话:如果你在获取数据的时候,想要对多的那一边的数据再进行一层过滤,那么这时候就可以考虑使用`lazy='dynamic'`。 lazy可用的选项: 1. `select`:这个是默认选项。还是拿`user.articles`的例子来讲。如果你没有访问`user.articles`这个属性,那么sqlalchemy就不会从数据库中查找文章。一旦你访问了这个属性,那么sqlalchemy就会立马从数据库中查找所有的文章,并把查找出来的数据组装成一个列表返回。这也是懒加载。 2. `dynamic`:这个就是我们刚刚讲的。就是在访问`user.articles`的时候返回回来的不是一个列表,而是`AppenderQuery`对象。