首页 > 解决方案 > SQLAlchemy 模型 @property 查询另一个模型

问题描述

我目前正在将 Flask 应用程序从Flask-SQLAlchemy包迁移到SQLAlchemy 1.4.2包。使用 Flask-SQLAlchemy 模型,我可以执行以下操作:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Author(db.Model):
    __tablename__ = 'authors'
    
    id = db.Column(db.String, primary_key=True)
    name = db.Column(db.String)
    surname = db.Column(db.String)

class Book(db.Model):
    __tablename__ = 'books'
    
    id = db.Column(db.String, primary_key=True)
    name = db.Column(db.String)
    year = db.Column(db.Integer)
    author_id = db.Column(db.String)
    
    @property
    def author(self):
        return Author.query.get(self.author_id)

然后我可以访问author一个对象的属性Book,它返回一个Author对象。假设我知道一本书,我想获取有关作者的信息,如下所示:

book: Book = Book.query.get(book_id)
author: Author = book.author

但是,对于SQLAlchemy,我必须使用session.get,这意味着我必须将当前会话作为参数传递:

class Book(db.Model):
    ...
    
    def author(self, session):
        return session.get(Author, author_id)

有没有办法保持book.author使用SQLAlchemy包的简单性?我对 pure 的经验很少SQLAlchemy,所以如果你能把我推向正确的方向,我将不胜感激。

编辑: 就我而言,在添加书籍时,系统不一定知道作者,在关系解决方案的情况下由于未知外键而导致错误。

标签: pythonsqlalchemyflask-sqlalchemy

解决方案


正如我在问题编辑中提到的那样,作者(或我正在研究的实际问题中的等价物)在添加本书时不一定是已知的。如果我在作者未知的情况下添加一本书,当我使用关系时,程序会因为未知的外键而引发错误。因此,在这种情况下,正确的解决方案是Ilja Everilä提出的解决方案。解决方案如下所示:

from sqlalchemy.orm import object_session

...

class Book(db.Model):
    ...

    @property
    def author(self):
        return object_session(self).get(Author, self.author_id)

推荐阅读