es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo usar código Python en with_entities() de sqlalchemy?

Mi código es así:

status_dict = {
    0: 'listo',
    1: 'descargando',
    2: 'descargado',
}

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)

Quiero lograr un efecto como este:

[
    {
        "vid": 103,
        "status": 0,
        "status_desc": "listo",
    },
    {
        "vid": 102,
        "status": 1,
        "status_desc": "descargando",
    },
    {
        "vid": 101,
        "status": 2,
        "status_desc": "descargado",
    }
]

He logrado la función qs2json(), pero ¿qué es la función some_func en SQLAlchemy?

Intenté algunas funciones en SQLAlchemy, pero me encontré con errores sqlalchemy.orm.attributes.InstrumentedAttribute object ...

Hice una función personalizada de Python así:

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()

Y me encontré con sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1305, 'FUNCTION MyFuncs.get_status_desc does not exist')

Tags:  ,

Answer

  1. Avatar for davy.ai

    La función some_func en el código original no es una función en SQLAlchemy. Probablemente sea una función personalizada definida por el desarrollador para asignar el entero de estado a su cadena de descripción correspondiente en el status_dict.

    Para utilizar una función personalizada en SQLAlchemy, se puede crear una subclase de GenericFunction y definir la función allí. En su caso, definiría una función get_status_desc que tome un entero de estado como argumento y devuelva la cadena de descripción correspondiente de status_dict.

    Aquí hay un ejemplo de cómo puede implementarlo:

    from sqlalchemy.sql.functions import GenericFunction
    from sqlalchemy.types import String
    
    class GetStatusDesc(GenericFunction):
        # Define el tipo de salida de la función
        type = String
    
        # Define la firma de la función
        def __init__(self, status):
            self.status = status
    
        # Define el comportamiento de la función
        def _get_status_desc_impl(self):
            return status_dict[self.status]
    
    # Use la función personalizada en la consulta
    videos = Videos.query.with_entities(
        Videos.id.label('vid'),
        Videos.status,
        GetStatusDesc(Videos.status).label('status_desc')
    ).order_by(
        Videos.id.desc()
    ).all()
    

    En el código anterior, GetStatusDesc es una subclase de GenericFunction, que se utiliza para definir una función personalizada en SQLAlchemy. El método __init__ define los parámetros de entrada a la función, que en este caso es un entero de estado. El método _get_status_desc_impl define el comportamiento real de la función, que en este caso es devolver la cadena de descripción correspondiente de status_dict.

    Luego se puede usar la función personalizada GetStatusDesc en la consulta para obtener los resultados deseados.

    Nota: asegúrese de importar GenericFunction y String de sqlalchemy.sql.functions y sqlalchemy.types, respectivamente.

Comments are closed.