Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 小马ORM-按特定顺序排列_Python_Sorting_Lambda_Ponyorm - Fatal编程技术网

Python 小马ORM-按特定顺序排列

Python 小马ORM-按特定顺序排列,python,sorting,lambda,ponyorm,Python,Sorting,Lambda,Ponyorm,执行小马ORM查询并尝试按模型上的三个属性对查询进行排序。首先按歌曲类型(可以是ssf\u type\u order\u map中列出的五个值之一),然后按持续时间(int)和uuid(string)排序 对于歌曲类型,我希望歌曲按以下顺序排序:完整、完整(器乐)、短片、循环、词干 如果我尝试使用以下.order\u by()调用进行排序,它不会返回任何错误,但不会按类型进行排序,因为我需要按上述顺序进行排序(尽管持续时间和UUID排序工作正常) 这是我认为最理想的查询,将字符串类型映射到对其排

执行小马ORM查询并尝试按模型上的三个属性对查询进行排序。首先按歌曲类型(可以是
ssf\u type\u order\u map
中列出的五个值之一),然后按持续时间(int)和uuid(string)排序

对于歌曲类型,我希望歌曲按以下顺序排序:完整、完整(器乐)、短片、循环、词干

如果我尝试使用以下
.order\u by()
调用进行排序,它不会返回任何错误,但不会按类型进行排序,因为我需要按上述顺序进行排序(尽管持续时间和UUID排序工作正常)

这是我认为最理想的查询,将字符串类型映射到对其排序的映射

ssf_type_order_map = {
    'Full': 1,
    'Full (Instrumental)': 2,
    'Shorts': 3,
    'Loops': 4,
    'Stems': 5
}

song_source_files = self.song_source_files.select(lambda ssf: True).order_by(lambda ssf: (ssf_type_order_map[ssf.type], ssf.duration, ssf.uuid))
但是我在运行这个语句时遇到了一个错误,即“Expression
ssf\u type\u order\u map
具有不支持的类型'dict'

order_by上的小马ORM文档在这种情况下使用lambdas时非常模糊

9月7日更新

我还尝试在模型上添加以下getter属性,如下所示:

@property
def source_type(self):
  ssf_type_order_map = {
    'Full': 1,
    'Full (Instrumental)': 2,
    'Shorts': 3,
    'Loops': 4,
    'Stems': 5
  }

  return ssy_type_order_map[self.type]
song_source_files = self.song_source_files.select(lambda ssf: True).order_by(lambda ssf: (ssf_type_order_map[ssf.type], ssf.duration, ssf.uuid))
然后,我尝试按如下方式对查询排序:

@property
def source_type(self):
  ssf_type_order_map = {
    'Full': 1,
    'Full (Instrumental)': 2,
    'Shorts': 3,
    'Loops': 4,
    'Stems': 5
  }

  return ssy_type_order_map[self.type]
song_source_files = self.song_source_files.select(lambda ssf: True).order_by(lambda ssf: (ssf_type_order_map[ssf.type], ssf.duration, ssf.uuid))
但是我收到一个错误,基本上说模型没有这个属性。我基于Django的ORM的一个类似问题的假设是,您只能访问数据库模型中存在的属性


如果小马也是这样的话,那么如何完成我想要完成的事情呢?

首先,我想说小马区分了两种类型的子表达式:外部表达式和相关表达式。外部表达式不依赖于生成器循环变量的值而相关表达式则是这样的。请考虑下面的例子:

从某个模块导入f,g
x=100
query=select(如果e.attr>f(x,200)和g(x,e),则e代表我的实体中的e)
在这个查询中,我们有两个子表达式:第一个是
f(x200)
,第二个是
g(x,e)
。前者被Pony视为外部表达式,因为它不使用任何循环变量。在这种情况下,Pony假设可以在查询执行之前用Python计算表达式的值,然后将表达式转换为单个参数。对于此类表达式,Pony对w可以在它们内部使用哪些Python函数,因为这样一个表达式的结果只是Python中计算的一个值

第二个表达式
g(x,e)
无法在Python中进行计算,因为它取决于循环变量
e
的值。对于不同的表行,这种表达式的结果可能不同。因此,Pony需要将这种表达式转换为SQL。并非每个Python表达式都可以转换为SQL,
g
需要是一个函数,Pony需要专门知道如何翻译。小马定义了可以翻译的Python操作的子集。该子集包括对数值类型的算术操作、字符串方法,如
startswith
endswith
in
等,以及聚合函数,如
sum
max

在代码中,当您编写

.order\u by(lambda ssf:(ssf\u type\u order\u map[ssf.type],ssf.duration,ssf.uuid))
表达式
ssf\u type\u order\u map[ssf.type]
引用对象变量
ssf
,因此每个表行的值不同,因此这是相关表达式,Pony需要将该表达式转换为SQL。目前Pony不知道如何执行此类特定转换,但原则上这是可行的。转换结果如下wing SQL
CASE
语句:

按案例排序ssf.type
当“满”时,则为1
当“满(乐器)”时,则为2
当“短裤”出现时,则为3
当“循环”时,则为4
什么时候“干”呢
其他0
结束
好消息是,如果表达式语法为:

(如果ssf.type=='Full'则为1,否则为
2如果ssf.type==‘完整(仪器)’否则
3如果ssf.type==‘短路’其他
4如果ssf.type=='Loops'else
5如果ssf.type=='茎',则为0)
目前,Pony还不支持反编译if表达式,因此如果您试图直接编写此类代码,您将遇到一个异常。作为一种解决方法,您需要将lambda函数的源作为字符串传递。在这种情况下,它将被正确翻译,因为我们可以直接将字符串解析为AST,而无需反编译。因此,您可以n写:

song\u source\u files=self.song\u source\u files.select().order\u by(“”)
lambda ssf:((如果ssf.type=='Full'其他,则为1)
2如果ssf.type==‘完整(仪器)’否则
3如果ssf.type==‘短路’其他
4如果ssf.type=='Loops'else
5如果ssf.type=='Stems'否则为0),
ssf.duration,ssf.uuid)
""")
这应该可以很好地工作,但我建议用另一种方法解决这个问题:我们可以让
SourceFileType
实体具有
name
code
属性,然后按
ssf.type.code
值排序
ssf
记录:

类源文件(db.Entity):
名称=必需(str)
类型=必需(lambda:SourceFileType)
持续时间=必需(时间增量)
uuid=必需(uuid.uuid,unique=True,default=uuid.uuid4)
类SourceFileType(db.Entity):
名称=必需(str)
代码=必需(整数)
files=Set(lambda:SongSourceFile)
然后就可以按以下方式编写查询:

song\u source\u files=self.song\u source\u files.select().order\u by(
lambda ssf:(ssf.type.code、ssf.duration、ssf.uuid)
)
我认为这种方法更通用,因为现在除了
name
code
之外,还可以向
SourceFileType
添加其他有用的属性