最近在做的东西,用上了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没有那么些约束就好了。
如果有,还请不吝赐教。