【问题标题】:What does cr.execute mean in OpenERP development?在 OpenERP 开发中 cr.execute 是什么意思?
【发布时间】:2013-12-11 05:23:31
【问题描述】:

我一直在尝试通过 Python 学习 Open ERP 模块开发。我想出了一个我认为我不理解的源代码。我在浏览时尝试了互联网上的几个链接,但找不到有用的链接。我需要非常了解这一点。

cr.execute("""
            SELECT a.id as id, COALESCE(MAX(l.date),a.purchase_date) AS date
            FROM account_asset_asset a
            LEFT JOIN account_move_line l ON (l.asset_id = a.id)
            WHERE a.id IN %s
            GROUP BY a.id, a.purchase_date """, (tuple(ids),))
        return dict(cr.fetchall())

请回复, 希望建议, 最良好的祝愿, 谢谢。

【问题讨论】:

  • 这肯定是它正在运行的 SQL 代码。所以cr 大概是一个数据库游标对象。有关更多详细信息,您需要检查在代码的其他部分中创建光标的位置。但是,您可以在 PEP 249 中了解 Python 数据库模块通常遵循的通用 API。
  • 我知道它是一个 db 游标,但我不明白它的工作方式
  • 我怀疑您需要详细解释代码以及您不理解的内容才能获得答案。例如,这段代码在哪里运行?你对它做什么了解(例如,你知道account_asset_assetaccount_move_line 表的用途)吗?

标签: python eclipse openerp


【解决方案1】:

只是想在这里补充几点,所以我认为它值得单独回答:

  • cr(游标)不是 psycopg2 游标,它是一个包含 psycopg2 游标的 OpenERP 类。它通常将大多数方法调用传递给封装的 psyco 游标,但它确实实现了一些自己的方法,例如关闭、执行等。在 OpenERP 7 中查看 sql_db.py

  • 纠正 Andrei 的例子,OpenERP 光标是不可迭代的,如果你尝试迭代它,你会看到:

    for row in cr:
    TypeError: 'Cursor' object is not iterable
    

    有一天我会在这方面提出一个错误。

  • fetchone 和 fetchall 方法被传递到底层 pscyo 游标,因此请阅读有关这些游标的标准文档。

  • 对于一般用途,如果您执行 cr.execute,则结果集仅存在于您执行 ORM 写入等其他操作之前。

  • cr.execute 通常仅用于特殊情况,或运行复杂的 SQL 连接等。只有在您确定 ORM 不会及时执行您想要的操作之后,它才应该是一种手段。

  • 永远不要尝试自己管理提供的 cr 对象上的事务。如果您需要这样做以防止长时间运行的事务(例如隔夜计算更新),请创建和管理您自己的游标。以经过认证的采购模块为例。

  • 在开始组装查询之前,请确保您了解什么是 SQL 注入以及使用查询参数的正确方法(查看 psycopg2 中游标类的文档)。

【讨论】:

    【解决方案2】:

    正如你所理解的,cr 是一个数据库游标。它允许您直接在数据库上执行 SQL 查询并获取结果。

    它的工作方式没什么特别的:

    执行SQL代码:

    cr.execute("some sql code")
    

    检索结果:

    cr.fetchone()
    cr.fetchall()
    etc...
    

    你也可以遍历光标:

    for rec in cr:
        print(rec)
    

    有关光标对象的更多信息,您可能需要查看Psycopg documentation

    在 OpenERP 中,cr 对象在 osv/orm 代码中的某处被初始化,并且在您作为 osv.osv 的子类创建的模型中可用。

    现在我很难过,我不得不注意到通常您不想在 OpenERP 中使用直接 SQL 查询。 OpenERP 为您提供整个对象关系模型(orm)作为数据库层的抽象。例如,如果您想在代码中的某处访问 account_asset_asset 模型,您应该更喜欢使用 orm 的 OpenERP 方法的“本机”:

    asset_obj = self.pool.get('account.asset.asset')
    asset_ids = asset_obj.search(cr, uid, [('date', '>', start_date), ('date', '<', end_date)])
    assets = asset_obj.browse(cr, uid, asset_ids, context=your_context)
    for asset in assets:
        print asset
    

    在某些特定情况下保留 cr 功能,因为“本机”方法会变得很糟糕。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-12
      • 2017-06-11
      • 2018-03-05
      • 2023-03-27
      • 2016-08-17
      • 2010-12-28
      • 2020-10-27
      • 2013-03-09
      相关资源
      最近更新 更多