首页 > 解决方案 > SQLAlchemy 选择多个列,如内连接

问题描述

我有用户、公司及其文章的数据库。多个用户可以在一个公司内部,并且用户可以创建文章。现在,我尝试让用户可以查看他们公司的文章。我通过 company_id 选择所有文章并使用 add_column 附加用户名,但结果,我有重复的记录:

[(<Article 1>, <User 1>), (<Article 1>, <User 2>), (<Article 2>, <User 1>), (<Article 2>, <User 2>)]

需要是这样的:

[(<Article 1>, <User 1>), (<Article 2>, <User 2>)]  - this articles with one article_company_id

我的代码:

user_id = current_user.id
# Here i get company_id of current user
company_id = User.query.filter_by(id=user_id).first().company_id
# Here i want to load all articles for company
article_list = Article.query.add_entity(User).filter_by(article_company_id=company_id).all()
        

数据库模型:

class User(UserMixin, db.Model):
    __tablename__ = 'user'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(100), unique=True)
    password = db.Column(db.String(100))
    name = db.Column(db.String(1000))
    company_id = db.Column(db.String(100))
    created = db.Column(db.String(100))
    rights_id = db.Column(db.String(100))
    gravatar = db.Column(db.String(100))
    

class Company(db.Model):
    __tablename__ = 'company'
    id = db.Column(db.Integer, primary_key=True)
    company_admin_id = db.Column(db.Integer)
    company_name = db.Column(db.String(100))


class Article(db.Model):
    __tablename__ = 'article'
    id = db.Column(db.Integer, primary_key=True)
    article_owner_id = db.Column(db.Integer, ForeignKey('user.id'))
    article_company_id = db.Column(db.Integer, ForeignKey('company.id'))
    article_creation_date = db.Column(db.String(100))
    article_status = db.Column(db.String(100))
    article_data = db.Column(db.JSON(100))
    article_name = db.Column(db.String(100))
 

正如您在屏幕截图中看到的那样,我有 2 篇文章,其中有一篇 article_company_id,因此我想从用户表中获取这两条记录,但它们的所有者名称。我怎样才能做到这一点?

标签: pythonflasksqlalchemyflask-sqlalchemy

解决方案


仅使用过滤器的问题article_company_id是它不会过滤掉用户,无论是您user_id在过滤器中包含的,还是您可以在此处使用连接并仅选择您需要的列,

例如

res = (
    db.session.query(Article.article_name, 
                     User.name)
    .join(User, Company)
    .all()
)

print(res[0].name)

推荐阅读