【问题标题】:How can I use python code in with_entities() of sqlalchemy?如何在 sqlalchemy 的 with_entities() 中使用 python 代码?
【发布时间】:2022-01-06 02:25:26
【问题描述】:

我的代码是这样的:

status_dict = {
    0: 'ready',
    1: 'downloading',
    2: 'downloaded',
}


class Videos(db.Model):
    __tablename__ = 'videos'
    id = db.Column(db.Integer, primary_key=True)
    status = db.Column(db.Integer, default=0, index=True)


class Test:

    @classmethod
    def run(cls):
        videos = Videos.query.with_entities(
            Videos.id.label('vid'),
            Videos.status,
            some_func(status_dict[Videos.status]).label('status_desc')
        ).order_by(
            Videos.id.desc()
        ).all()

        rows = qs2json(videos)

我想达到这样的效果:

[
    {
        "vid": 103,
        "status": 0,
        "status_desc": "ready",
    },
    {
        "vid": 102,
        "status": 1,
        "status_desc": "downloading",
    },
    {
        "vid": 101,
        "status": 2,
        "status_desc": "downloaded",
    }
]

我已经实现了函数qs2json(),但是SQLAlchemy中的函数some_func是什么?

我在 SQLAlchemy 中尝试了一些函数,但遇到了错误

我做了一个这样的自定义python函数:

from sqlalchemy.sql.functions import GenericFunction, func
from sqlalchemy.types import String


class MyFuncs(GenericFunction):
    type = String

    def get_status_desc(self, status):
        return status_dict[status]


class Test:

    @classmethod
    def run(cls):
        videos = Videos.query.with_entities(
            Videos.id.label('vid'),
            Videos.status,
            func.MyFuncs.get_status_desc(Videos.status).label('status_desc')
        ).order_by(
            Videos.id.desc()
        ).all()


我遇到了sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1305, 'FUNCTION MyFuncs.get_status_desc does not exist')

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    为此使用case,作为您的示例:

    import sqlalchemy as sa
    class Videos(db.Model):
        __tablename__ = 'videos'
        id = db.Column(db.Integer, primary_key=True)
        status = db.Column(db.Integer, default=0, index=True)
    
        @classmethod
        def as_dict(cls, obj):
            return dict(obj)
    
    
    videos = Videos.query.with_entities(
        Videos.id.label('vid'),
        Videos.status,
        sa.case([(Videos.status == k, v) for k, v in status_dict.items()]).label('status_desc')
    ).order_by(
        Videos.id.desc()
    ).all()
    
    json_data = json.dumps([Videos.as_dict(v) for v in videos])
    
    print(json_data)
    # [{"vid": 3, "status": 1, "status_desc": "downloading"}, {"vid": 2, "status": 2, "status_desc": "downloaded"}, {"vid":
    # 1, "status": 0, "status_desc": "ready"}]
     
    

    【讨论】:

    • 非常感谢,它有效!但是,这不是我想要的确切答案。我想知道 SQLAlchemy 中是否有一个函数允许我在 some_func 函数中放置一个 python 函数或一些 python 值。如果我需要一个 python func 来计算 .label('some_label') 的值
    • 不仅仅是python函数,你可以尝试使用func,甚至可以使用GenericFunction编写你自己的
    • 我编辑了我的问题,但遇到了错误。我不太了解GenericFunction,因为它的例子不够详细,我在网上也很少找到它。请你帮我一个正确的例子MyFuncs
    • 这个不行,因为直接把你的函数转成SQL是不可能的,看func模块支持什么:count、min、max、coalesce等,都是数据库本身支持的。我相信从技术上讲可以实现您自己的此类功能(可以在 sql 中使用),但在您的情况下它确实是过度工程。就用case,这里是对的方式
    猜你喜欢
    • 2016-12-01
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多