【问题标题】:Posgres Record does not exits while fetching获取时 Postgres 记录不存在
【发布时间】:2015-09-10 12:57:02
【问题描述】:

我正在循环中从数据库中获取记录行。在循环中还有一些选择查询,其中重新记录不退出..

我写了这个视图

CREATE view get_application_views AS
SELECT application_id, coalesce(SUM(views),0) as views FROM employer_applicationstats GrOUP BY application_id;

然后在这个循环中..

SELECT views FROM get_application_views WHERE application_id = '5605617';

对于application_id 5605617,没有记录存在,所以我的python脚本引发错误并停止循环。s

我该如何处理这种情况?

更新:

def get_application_view(application_id):
    try:
        cursor = connection.cursor()
        sql_query = "SELECT views FROM get_application_views WHERE application_id = '"+str(application_id)+"';"
        cursor.execute(sql_query)
    except Exception as e:
        print e
        status = 0
        return status
    else:
            ver = cursor.fetchone()
            status = ver[0]
        return status

对于 application_id = 5605617 它说,

status = ver[0]
TypeError: 'NoneType' object has no attribute '__getitem__'

【问题讨论】:

  • 我们应该怎么知道?您没有显示任何脚本。
  • 立即查看更新问题

标签: python postgresql function views


【解决方案1】:

您的代码中没有if 语句:

def get_application_view(application_id):
        status='1'
        cursor = connection.cursor()
        sql_query = "SELECT views FROM get_application_views WHERE application_id = '{id}';".format(id=application_id)
        try:            
           cursor.execute(sql_query)
        except Exception as e:
           print e
           status = 0
        else:
            # do something
        return status

我还建议使用 .format() 方法,因为它更简洁,尤其是 SQL 引号。

【讨论】:

  • 我希望这个异常是handeled on Database side,因为我得到的数据高于10k,并且在Python上进行这个计算,当计算时间超过30秒时我得到request timeout error .
  • 仍然收到status = ver[0] TypeError: 'NoneType' object has no attribute '__getitem__'
  • 我不确定我是否完全理解上下文,但是将 try/except 包裹在查询的实际执行中怎么样?我更新了我的答案以证明我的意思
【解决方案2】:

cursor.fetchone() 在没有获取任何内容时返回 None。所以你的原始代码看起来像

def get_application_view(application_id):
    try:
        cursor = connection.cursor()
        sql_query = "SELECT views FROM get_application_views WHERE application_id = '"+str(application_id)+"';"
        cursor.execute(sql_query)
    except Exception as e:
        print e
        status = 0
        return status
    else:
        ver = cursor.fetchone()
        if ver:        
            status = ver[0]
        else:
            status = 0
        return status

另外,我更喜欢从 @celenius 的答案中给出的 try..except 中取出游标对象创建和返回语句。

我们可以将 if..else.. 块转换为 conditional expressionstatus = ver[0] if ver else 0

【讨论】:

    【解决方案3】:

    在读出 postgres 函数后,我将我的代码更改为类似的内容。

    CREATE OR REPLACE FUNCTION get_application_views(application_id integer, OUT views bigint)
    RETURNS bigint
    LANGUAGE sql
    AS $function$
    SELECT coalesce((select sum(views) as views from employer_applicationstats where application_id = $1 GROUP BY application_id), 0);
    $function$
    

    def get_application_view(application_id):
            cursor = connection.cursor()
            sql_query = "SELECT * FROM get_application_views('{id}')".format(id=application_id)
            try:            
               cursor.execute(sql_query)
            except Exception as e:
               return 0
            else:
                ver = cursor.fetchone()
                status = ver[0]
                return status
    

    感谢@celenius

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-14
      • 2022-01-11
      • 2019-11-22
      • 2014-10-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      相关资源
      最近更新 更多