繁体   English   中英

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

[英]In my MapperExtension.create_instance, how can I extract individual row data by column name?

我有一个查询,该查询返回相当数量的行,并且发现

  • 我们最终放弃了大多数关联的ORM实例;
  • 建立那些即将被抛弃的实例非常缓慢。

因此,我只想构建所需的实例!

不幸的是,我不能仅仅通过限制查询来做到这一点。 我需要在每一行上都做一些“业务逻辑”处理,然后才能知道是否将其丢弃。 我无法在SQL中执行此操作。

所以我想我可以使用MapperExtension来处理这个问题:我将MapperExtension子类化,然后覆盖create_instance; 该方法将检查行数据,如果该数据值得构建到实例中,则返回EXT_CONTINUE,否则返回其他信息(我尚未决定什么)。

首先,这种方法是否有意义?

其次,如果确实有意义,我还没有弄清楚如何在传递给create_instance的参数中找到所需的数据。 我怀疑它在某个地方,但是很难找到……与其得到直接对应于我感兴趣的特定类的行,还不如得到对应于SQLalchemy生成的查询的行,这种情况会发生(例如)表A,B和C之间的连接有些复杂。

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

我假设在映射器,selectcontext或class_参数内部的某处是表的列之间的某种映射,并且偏移到行中。 但是我还没有找到正确的东西。 不过,我非常接近。 例如,我发现selectcontext.statement.columns包含生成的列的名称...但不包含我感兴趣的表的名称。例如:

Column(u'A_id', UUID(), ...
...
Column(u'%(32285328 B)s_weight, MSInt(), ...
...
Column(u'%(32285999 C)s_height', MSInt(), ...

因此:如何将列名(如C.height)映射到行中的偏移量?

该行接受Column对象作为索引:

row[MyClass.some_element.__clause_element__()]

但这只会使您尽可能地从外部访问您可以访问的类和aliased()构造。 这很可能就是您要解决的那部分问题的全部内容(即使最终这个想法行不通,请继续阅读)。

如果您的语句包含子查询,从使用from_self()或join()之类的东西到多态目标,则create_instance()方法无法为您提供实现该目标所需的翻译功能。

如果您要获取链接到eagerload()的行,那完全不是您应该做的事情。 eagerload()关于优化集合的负载。 如果您希望查询在两个表之间进行联接,并且希望对联接的表进行过滤,请使用join()。

但最重要的是,create_instance()来自SQLAlchemy的0.1版,我怀疑有人将它用于任何用途,并且它没有能力说“跳过这一行”。 它必须返回某些东西,否则映射器将自行创建实例。 因此,无论您对行的解释有多好,这里都没有想要执行的操作。

如果我真的想做这样的事情,则可能更容易对返回的ResultProxy的“ fetchall()”方法进行猴子修补,以过滤行并将其发送到Query.instances()。 任何结果都可以发送到此方法。 虽然,如果Query已经完成翻译等操作,则它还需要原始QueryContext才能知道如何翻译。 但这都不是我的烦恼。

总体而言,如果在所有这些方面速度都是至关重要的问题,以至于创建对象有很大的不同,那么我会做到这一点,以便在整个操作过程中根本不需要映射的对象,或者d使用缓存,或从结果集中手动生成所需的对象。 我还要确保可以访问我正在使用的可选对象中的所有目标列,以便可以从结果行中重新获取,这意味着我要么不在ORM中使用自动子查询/别名生成功能,或者我直接使用表达语言(如果您确实渴望速度,并且想编写大量优化代码,则可能应该只使用表达语言)。

因此,您必须在这里提出的真正问题是:

  1. 您是否已验证速度的真正差异是从行创建对象。 即不获取行或获取其列等。
  2. 该行是否只有一些不需要的昂贵列? 您研究过deferred()吗?
  3. 这些业务规则是什么?为什么不能用SQL,存储过程等方式完成这些业务规则?
  4. 您实际上在这里跳过了几千行,以至于它“慢”到不“跳过”它们
  5. 您是否研究了使对象已经存在的技术,例如内存中的缓存,预加载等。对于许多情况,这很合适。
  6. 所有这些都不起作用,您真的想破解一些家用优化代码。 那么为什么不直接使用SQL表达式语言呢? 如果最终您只是在处理视图层,则结果行非常友好(它们允许“属性”样式访问等),或者从中构建一些快速的“生成对象”例程。 ORM展示了SQL表达式语言的一个非常特定的用例,如果您确实需要比它轻得多的东西,最好跳过它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM