Django中对PostgreSQL存储的pip包版本号正确排序的方法咨询
Django 中 PostgreSQL 版本号字段正确排序方案
问题原因
原方案直接对字符串类型的版本号排序,是按字符逐位比较的逻辑:0.9.1中的第3位字符9大于0.21.1中的第3位字符2,所以会被误判为更大的版本,不符合语义化版本按分段数字比较的规则。
最优实现方案(数据库层面处理,性能最优)
直接借助 PostgreSQL 内置的字符串拆分函数,在 ORM 查询时把版本号拆分为三个数字字段排序,不需要修改表结构,也兼容带前导零的版本号(比如01.9.1、14.12.03):
from django.db.models import IntegerField from django.db.models.functions import Cast, SplitPart latest_version = Version.objects.filter(package='example').annotate( # 按点拆分版本号,分别取出三段并转为整数 major = Cast(SplitPart('version', '.', 1), output_field=IntegerField()), minor = Cast(SplitPart('version', '.', 2), output_field=IntegerField()), patch = Cast(SplitPart('version', '.', 3), output_field=IntegerField()) # 按三段数字倒序排序,第一个结果就是最新版本 ).order_by('-major', '-minor', '-patch').first()
备选轻量方案(小数据量适用)
如果对应包的版本数量很少,可以把数据拉到应用层用PyPI官方的版本比较逻辑处理:
from packaging.version import Version as PyPIVersion # 取出指定包的所有版本号 version_list = Version.objects.filter(package='example').values_list('version', flat=True) # 直接用PyPI的版本规则取最大值 latest_version = max(version_list, key=lambda v: PyPIVersion(v))
内容的提问来源于stack exchange,提问作者ddjjaannggoo
相关产品推荐
相关产品推荐

