Order_By 在 peewee 中为 SQLite 自定义日期
Order_By custom date in peewee for SQLite
我在构建数据库时犯了一个巨大的错误,但除了 1 个功能外,它工作得很好。在所有需要更改程序才能使该功能正常工作的地方更改程序将是数周的艰巨工作,所以我们希望这个解决方法是可能的。
问题: 我在 SQLite 数据库中将数据存储为“dd/mm/yyyy”TextField
格式而不是 DateField
。
需要: 我需要在联合查询中按日期排序,以按照我的自定义日期格式获取该联合中的最后 number
条记录。它们来自不同的表,所以我不能只使用 rowid 或类似的东西来获取最后一个,我需要按日期来做,而且我不能更改数据库中已经存储的数据,因为已经创建了发票使用该格式(“dd/mm/yyyy”是我国的默认日期格式)。
这是捕获数据的查询:
records = []
limited_to = 25
union = (facturas | contado | albaranes | presupuestos)
for record in (union
.select_from(union.c.idunica, union.c.fecha, union.c.codigo,
union.c.tipo, union.c.clienterazonsocial,
union.c.totalimporte, union.c.pagada,
union.c.contabilizar, union.c.concepto1,
union.c.cantidad1, union.c.precio1,
union.c.observaciones)
.order_by(union.c.fecha.desc()) # TODO this is what I need to change.
.limit(limited_to)
.tuples()):
records.append(record)
现在让事情变得更复杂的是,在将每个数据库转换为联合查询之前,联合已经由一个非常复杂的 where
子句创建。
所以我唯一的希望是:有没有办法让 order_by
遵循自定义日期格式?
澄清一下,这是我需要遵循 order_by
子句的简单转换,因为我假设如果这是日期格式,SQLite 排序不会有问题:
def reverse_date(date: str) -> str:
"""Reverse the date order from dd/mm/yyyy dates into yyyy-mm-dd"""
yyyy, mm, dd = date.split("/")
return f"{yyyy}-{mm}-{dd}"
注意:我省略了很多代码,因为我认为这是不必要的。这是理解问题所需的最少代码量。如果您需要更多数据,请告诉我。
更新: 尝试这个解决方法,它似乎工作正常。需要更多测试,但很有希望。如果有人遇到同样的问题,请看这里:
.order_by(sqlfunc.Substr(union.c.fecha, 7)
.concat('/')
.concat(sqlfunc.Substr(union.c.fecha, 4, 2))
.concat('/')
.concat(sqlfunc.Substr(union.c.fecha, 1, 2))
.desc())
2020 年末快乐!
正如您所指出的,如果您希望日期正确排序,它们需要采用 yyyy-mm-dd
格式,这是您应该始终 使用的文本格式在 SQLite 中(或具有相同年、月、日、顺序的东西)。
您可以在这里使用 re.sub
进行重新排列:
.order_by(re.sub(r'(\d{2})/(\d{2})/(\d{4})', r'--',
union.c.fecha))
这里我们使用正则表达式在单独的捕获组中捕获年、月和日组件。然后,我们按照正确的顺序替换这些组件进行排序。
我在构建数据库时犯了一个巨大的错误,但除了 1 个功能外,它工作得很好。在所有需要更改程序才能使该功能正常工作的地方更改程序将是数周的艰巨工作,所以我们希望这个解决方法是可能的。
问题: 我在 SQLite 数据库中将数据存储为“dd/mm/yyyy”TextField
格式而不是 DateField
。
需要: 我需要在联合查询中按日期排序,以按照我的自定义日期格式获取该联合中的最后 number
条记录。它们来自不同的表,所以我不能只使用 rowid 或类似的东西来获取最后一个,我需要按日期来做,而且我不能更改数据库中已经存储的数据,因为已经创建了发票使用该格式(“dd/mm/yyyy”是我国的默认日期格式)。
这是捕获数据的查询:
records = []
limited_to = 25
union = (facturas | contado | albaranes | presupuestos)
for record in (union
.select_from(union.c.idunica, union.c.fecha, union.c.codigo,
union.c.tipo, union.c.clienterazonsocial,
union.c.totalimporte, union.c.pagada,
union.c.contabilizar, union.c.concepto1,
union.c.cantidad1, union.c.precio1,
union.c.observaciones)
.order_by(union.c.fecha.desc()) # TODO this is what I need to change.
.limit(limited_to)
.tuples()):
records.append(record)
现在让事情变得更复杂的是,在将每个数据库转换为联合查询之前,联合已经由一个非常复杂的 where
子句创建。
所以我唯一的希望是:有没有办法让 order_by
遵循自定义日期格式?
澄清一下,这是我需要遵循 order_by
子句的简单转换,因为我假设如果这是日期格式,SQLite 排序不会有问题:
def reverse_date(date: str) -> str:
"""Reverse the date order from dd/mm/yyyy dates into yyyy-mm-dd"""
yyyy, mm, dd = date.split("/")
return f"{yyyy}-{mm}-{dd}"
注意:我省略了很多代码,因为我认为这是不必要的。这是理解问题所需的最少代码量。如果您需要更多数据,请告诉我。
更新: 尝试这个解决方法,它似乎工作正常。需要更多测试,但很有希望。如果有人遇到同样的问题,请看这里:
.order_by(sqlfunc.Substr(union.c.fecha, 7)
.concat('/')
.concat(sqlfunc.Substr(union.c.fecha, 4, 2))
.concat('/')
.concat(sqlfunc.Substr(union.c.fecha, 1, 2))
.desc())
2020 年末快乐!
正如您所指出的,如果您希望日期正确排序,它们需要采用 yyyy-mm-dd
格式,这是您应该始终 使用的文本格式在 SQLite 中(或具有相同年、月、日、顺序的东西)。
您可以在这里使用 re.sub
进行重新排列:
.order_by(re.sub(r'(\d{2})/(\d{2})/(\d{4})', r'--',
union.c.fecha))
这里我们使用正则表达式在单独的捕获组中捕获年、月和日组件。然后,我们按照正确的顺序替换这些组件进行排序。