Python 在我的MapperExtension.create_实例中,如何按列名提取单个行数据?

Python 在我的MapperExtension.create_实例中,如何按列名提取单个行数据?,python,sqlalchemy,Python,Sqlalchemy,我得到了一个返回相当多行的查询,并且发现 我们最终扔掉了大部分相关的ORM实例;及 构建那些即将被丢弃的实例相当缓慢 所以我只想构建我需要的实例 不幸的是,我不能通过简单地限制查询来做到这一点;我需要对每一行进行相当多的“业务逻辑”处理,然后才能判断是否将其丢弃;我无法在SQL中执行此操作 所以我想我可以使用MapperExtension来处理这个问题:我将MapperExtension子类化,然后重写create_实例;该方法将检查行数据,如果数据值得构建到实例中,则返回EXT_CONTI

我得到了一个返回相当多行的查询,并且发现

  • 我们最终扔掉了大部分相关的ORM实例;及
  • 构建那些即将被丢弃的实例相当缓慢
所以我只想构建我需要的实例

不幸的是,我不能通过简单地限制查询来做到这一点;我需要对每一行进行相当多的“业务逻辑”处理,然后才能判断是否将其丢弃;我无法在SQL中执行此操作

所以我想我可以使用MapperExtension来处理这个问题:我将MapperExtension子类化,然后重写create_实例;该方法将检查行数据,如果数据值得构建到实例中,则返回EXT_CONTINUE,或者。。。还有别的事情(我还没决定怎么办)

首先,这种方法有意义吗

其次,如果它确实有意义的话,我还没有弄清楚如何在传递给
create\u instance
的参数中找到所需的数据。我怀疑它在那里的某个地方,但很难找到。。。我得到的不是直接对应于我感兴趣的特定类的行,而是对应于SQLalchemy生成的查询的行,这恰好是(比如)表a、B和C之间的一个有点复杂的连接

问题是我不知道行中的哪些元素对应于ORM类中的字段:我希望能够提取(例如)A.id、B.weight和C.height

我假设在映射器、selectcontext或class_uu参数中的某个地方是表的列之间的某种映射,以及到行中的偏移量。但我还没有找到合适的东西。不过,我已经非常接近了。例如,我发现
selectcontext.statement.columns
包含生成的列的名称。。。但不是我感兴趣的那张桌子。例如:

Column(u'A_id', UUID(), ...
...
Column(u'%(32285328 B)s_weight, MSInt(), ...
...
Column(u'%(32285999 C)s_height', MSInt(), ...
那么:如何将诸如C.height之类的列名映射到
行?

行接受列对象作为索引:

row[MyClass.some_element.__clause_element__()]
但这只会让您在外部访问类和别名()构造。这很可能就是你在这部分问题上所需要的全部(尽管最终这个想法行不通,请继续阅读)

如果语句中包含了子查询,从使用from_self()或join()到多态目标,那么create_instance()方法不会让您访问完成此任务所需的转换函数

如果您试图获取链接到acequeload()的行,那么这完全不是您应该做的事情。热心加载()是关于优化集合的加载。如果希望查询在两个表之间联接,并且希望对联接的表进行筛选,请使用join()

但最重要的是,create_instance()来自SQLAlchemy的0.1版,我怀疑是否有人将其用于任何用途,而且它没有说“跳过这一行”的能力。它必须返回一些东西,否则映射程序将自己创建实例。因此,无论你如何理解这一行,这里没有你想做的事情

如果我真的想做这样的事情,那么将返回的ResultProxy的“fetchall()”方法monkeypatch以筛选行并将其发送到Query.instances()可能会更容易。任何结果都可以发送到此方法。尽管如此,如果查询已经对映射的selectables进行了翻译等操作,它还需要原始的QueryContext来知道如何翻译。但这也不是我要担心的

总的来说,如果在整个过程中,速度对一个问题非常关键,以致于创建对象有那么大的不同,我会这样做,以便在整个操作中根本不需要映射对象,或者使用缓存,或者从结果集中手动生成所需的对象。我还要确保我可以访问我正在使用的可选列中的所有目标列,以便可以从结果行重新获取,这意味着我要么不在ORM中使用自动子查询/别名生成函数,要么直接使用表达式语言(如果您真的渴望速度,并且有心情编写大量优化代码,那么您应该只使用表达式语言)

所以你在这里要问的真正问题是:

  • 您是否验证了速度上的真正差异是从行创建对象,即不获取行或获取其列,等等
  • 行中是否有一些您不需要的昂贵列?是否查看了deferred()
  • 这些业务规则是什么?为什么不能用SQL、存储过程等来实现
  • 你到底跳过了多少行,以至于不“跳过”它们太“慢”了
  • 您是否研究过让对象已经存在的技术,如内存缓存、预加载等。对于许多场景,这符合要求
  • 所有这些都不起作用,而且你真的想修改一些自制的优化代码。那么为什么不直接使用SQL表达式语言呢?如果最终你只是处理一个视图层,那么结果行是非常友好的(它们允许“属性”样式的访问等等),或者构建一些快速的“生成对象”ORM提供了SQL表达式语言的一个非常具体的用例,如果你真的需要比它轻得多的东西,最好跳过它

  • 行接受列对象作为索引:

    row[MyClass.some_element.__clause_element__()]
    
    但这只会让你了解到你在外部可以访问的类和别名()构造。这很可能是你在这一部分问题上所需要的全部(尽管最终这个想法行不通,请继续阅读)

    如果您的语句有子查询: