2022-01-19.tortoise-orm执行原生sql语句

最近在做的东西,用上了fastapi+tortoise-orm的技术方案。
在fastapi的models.py中,一般是这样写的:

from tortoise import Model, fields

class TableA(Model):
    idx = fields.IntField(pk=True)
    product = fields.CharField(max_length=60, null=True)
    price = fields.CharField(max_length=60, null=True)
    create_date = fields.DatetimeField()

    @classmethod
    async def get_by_product(cls, product):
        """ 根据product获取数据 """
        result = await cls.get_or_none(product=product)
        return result

这时候,想用一些原生sql语句执行一些复杂的查询,tortoise提供了一个raw()方法。一般会使用下面的写法:

@classmethod
async def get_count_by_year(cls):
    result = await cls.raw("SELECT year(create_date) FROM TableA GROUP BY year(create_date)")

按此执行,一般会报错,显示keyError year(create_date)之类的信息。

实际上这个问题非常容易解决。只需要在class TableA中声明SELECT的字段就行,即将class修改为如下:

class TableA(Model):
    idx = fields.IntField(pk=True)
    product = fields.CharField(max_length=60, null=True)
    price = fields.CharField(max_length=60, null=True)
    create_date = fields.DatetimeField()
    year_date = fields.CharField(max_length=60, null=True)

并将year(create_date)的结果储存为year_date字段,形如以下:

@classmethod
async def get_count_by_year(cls):
    result = await cls.raw("SELECT year(create_date) as year_date FROM TableA GROUP BY year(create_date)")

这样就可以了。

以上,如果有错误,还请留言批评指正。

2022-01-22 增加:

上文这个方法有问题,这样做了之后,还是会报错:"Unknown column..."
还得在SQL的表里增加对应的字段……这虽然可以使用了,但是很丑。

如果有什么更好的方法,还请不吝赐教。

2022-01-22 增加:

找到一个方法。将models.py 增加引入:

from tortoise import Tortoise

并编辑方法:

@classmethod
async def get_by_query(cls, query):
    db = Tortoise.get_connection("default")
    result = await db.execute_query_dict(query)
    return result

这时候,就不需要按文章开头的做法,增加字段,也不需要在SQL的表中增加字段了。

不过,需要注意的是,上面方法获取的结果为dict组成的list,dict的keys为表的字段名(带类型),在使用时无法直接用类的属性获取,需要特别注意。

哎,如果能使用raw()方法,并且对key没有那么些约束就好了。
如果有,还请不吝赐教。

你可能感兴趣的:(2022-01-19.tortoise-orm执行原生sql语句)