python - Flask-SQLAlchemy 关系列的总和

标签 python flask sqlalchemy flask-sqlalchemy

我确实有 2 个这样的类(class) =>

class User(db.Model):
    __tablename__ = "user"
    user_id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(32), unique=True, nullable=False)
    password = db.Column(db.String(77), unique=False, nullable=False)
    server_limit = db.Column(db.Integer, unique=False, nullable=False, server_default="4")
    servers = db.relationship('Server', backref='owner', lazy='dynamic')

class Server(db.Model):
    __tablename__ = "server"
    server_id = db.Column(db.Integer, primary_key=True)
    server_admin = db.Column(db.Integer, db.ForeignKey("user.user_id"))
    server_port = db.Column(db.Integer, unique=False, nullable=False)
    server_slot = db.Column(db.Integer, unique=False, nullable=False, server_default="32")

现在我正在尝试获取 server_slot 列的总和,例如 user_id 为 1。

我知道有关此问题的答案已被接受,但不同之处在于我尝试使用我在 User 类中分配的服务器( db.relationship )来完成此操作。

我使用为 User 类创建的替代方法 =>

def used(self):
    return db.session.execute("SELECT SUM(server.server_slot) FROM server WHERE server_admin={}".format(self.user_id)).scalar()

我该如何使用 db.session.query() 来做到这一点? 我正在寻找可以从 db.session.query(User).all() 获取的东西

我不想使用db.session.query(db.func.sum(Server.server_slot)).filter_by(server_admin=self.user_id).scalar()因为我将一个列表传递到我的 Flask 页面,该列表是由 db.session.query(User).all() 创建的所以我可以使用 Jinja2 模板中的 for 循环对其进行迭代,并在列表中显示每个用户信息,如下所示 =>

{% for user in users %}
    <td>user.username</td>
    <td>user.server_limit</td>
    <td>...</td>
    <td>user.used_slots()</td>
{% endfor %}

我可以使用user.servers.value("server_slot")但它只返回第一台服务器的 server_slot,我也尝试迭代 user.servers.all()所以我可以在嵌套循环内对它们的 server_slot 求和,但我无法在循环内为变量分配任何值并将其获取到循环外。

如果我的问题不够清楚,请告诉我(因为我知道可能是这样)。

最佳答案

定义 hybrid property/expression在您的用户模型上。

一个简单的独立示例(我简化了您的模型):

import random
from select import select
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import func
from sqlalchemy.ext.hybrid import hybrid_property

app = Flask(__name__)

# Create in-memory database
app.config['DATABASE_FILE'] = 'sample_db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
db = SQLAlchemy(app)


class User(db.Model):
    __tablename__ = "user"
    user_id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(32), unique=True, nullable=False)
    servers = db.relationship('Server', backref='owner', lazy='dynamic')

    @hybrid_property
    def server_slot_count(self):
        return sum(server.server_slot for server in self.servers)

    @server_slot_count.expression
    def server_slot_count(cls):
        return (
            select([func.sum(Server.server_slot)]).
            where(Server.server_admin == cls.user_id).
            label('server_slot_count')
        )


class Server(db.Model):
    __tablename__ = "server"
    server_id = db.Column(db.Integer, primary_key=True)
    server_admin = db.Column(db.Integer, db.ForeignKey("user.user_id"))
    server_slot = db.Column(db.Integer, unique=False, nullable=False, server_default="32")


@app.route('/')
def index():
    html = []
    for user in User.query.all():
        html.append('User :{user}; Server Count:{count}'.format(user=user.username, count=user.server_slot_count))

    return '<br>'.join(html)


def build_sample_db():
    db.drop_all()
    db.create_all()

    for username in ['DarkSuniuM', 'pjcunningham']:

        user = User(
            username=username,
        )
        db.session.add(user)
        db.session.commit()
        for slot in random.sample(range(1, 100), 5):
            server = Server(
                server_admin=user.user_id,
                server_slot=slot
            )
            db.session.add(server)

        db.session.commit()


if __name__ == '__main__':
    build_sample_db()
    app.run(port=5000, debug=True)

您的用户模型现在有一个属性server_slot_count

{% for user in users %}
    <td>user.username</td>
    <td>user.server_limit</td>
    <td>...</td>
    <td>user.server_slot_count</td>
{% endfor %}

关于python - Flask-SQLAlchemy 关系列的总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48537626/

相关文章:

python - 如何加速numpy张量*张量运算

python - 允许单个 IP 使用 HTTPBasicAuth 通过 Flask 进行身份验证

python - 在 AWS Lambda 中使用 Python SQLAlchemy 是个好主意吗?

python - 如何在 flask 中共享全局应用对象?

python - 重试失败的 sqlalchemy 查询

python - flask SQLalchemy : relationships between different modules

python - Tweepy:[Errno 8] 节点名或服务名已提供,或未知

python - 在 svg 内的路径中查找 XPath

python - PyQt5 QLCD数字显示

python - pytest 看不到正在测试的函数的日志