如何使用SQLAlchemy按ID查询Model

时间:2016-11-18 01:38:42

标签: python sqlalchemy flask-sqlalchemy

有两个表:" User"和"项目"定义如下:

create table user (
  id integer primary key autoincrement
);

create table project (
  id integer primary key autoincrement,
  user_id integer
);

第三个表用于将用户映射到项目ID:

create table users_to_projects_table (
  user_id integer,
  project_id integer
);

在Python中,我首先声明关系表:

users_to_projects_table = db.Table('users_to_projects_table',
    db.Column('user_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('project_id', db.Integer, db.ForeignKey('project.id'))
)

然后我继续为ProjectUser表创建类:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    projects = db.relationship('Project', backref='user', lazy='dynamic')


class Project(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    _users = db.relationship('User', secondary=users_to_projects_table, backref=db.backref('users_to_projects_backref', lazy='dynamic'))

    @property
    def users(self):
        return self._users

    @users.setter
    def users(self, user_ids):
        self._users = [User.query.filter_by(id=user_id).one() for user_id in user_ids]

现在一切都完成后,我继续创建user

user = User()
db.session.add(user)
db.session.commit()

接下来,我通过将project作为参数传递来创建user.id

project = Project( users=[user.id] )
db.session.add(project)
db.session.commit()

一切看起来都不错。我可以看到userproject都写入了数据库。并且users_to_projects_table已使用project_id正确更新,并与user_id相关联。

问题:现在users_to_projects_table"知道"哪个user_id对应哪个project_id如何查询哪些用户链接到哪个项目? 以下命令失败,并显示InvalidRequestError

project_id = 1
User.projects.query.filter_by(project_id=project_id)

错误如下:

InvalidRequestError: Entity '<class '_app.User'>' has no property 'project_id'

需要改变什么才能使其有效?

1 个答案:

答案 0 :(得分:1)

您需要在secondary=users_to_projects_table关系中设置projects

可能的查询是User.query.filter(User.projects.any(id=project_id)),尽管使用连接可能会更好。

使用连接可能更快(尽管更长)的查询:

User.query.select_from(User).join(users_to_projects_table).join(Project).filter(Project.id==project_id