【问题标题】:Checking if a postgresql table exists under python (and probably Psycopg2)检查python下是否存在postgresql表(可能还有Psycopg2)
【发布时间】:2010-12-24 20:26:24
【问题描述】:

如何使用 Psycopg2 Python 库确定表是否存在?我想要一个真或假布尔值。

【问题讨论】:

    标签: python postgresql psycopg2


    【解决方案1】:

    怎么样:

    >>> import psycopg2
    >>> conn = psycopg2.connect("dbname='mydb' user='username' host='localhost' password='foobar'")
    >>> cur = conn.cursor()
    >>> cur.execute("select * from information_schema.tables where table_name=%s", ('mytable',))
    >>> bool(cur.rowcount)
    True
    

    使用 EXISTS 的替代方法更好,因为它不需要检索所有行,而只需至少存在一个这样的行:

    >>> cur.execute("select exists(select * from information_schema.tables where table_name=%s)", ('mytable',))
    >>> cur.fetchone()[0]
    True
    

    【讨论】:

    • 关闭但最好使用exists()。 :)
    • 我加了,但为什么它“更好”?
    • @Peter 更好,因为它只需要找到匹配where 条件的第一行,而rowcount 则必须检索所有行。
    • 我喜欢exists() 解决方案,但您应该使用cur.fetcone()[0] 而不是bool(cur.rowcount)(此请求总是返回一个值,其中第一列是exists() 结果,True 或False)
    • 执行 1 次后,我不断收到此错误:psycopg2.InternalError: current transaction is aborted, commands ignored until end of transaction block
    【解决方案2】:

    我不知道具体的 psycopg2 库,但是可以使用以下查询来检查表是否存在:

    SELECT EXISTS(SELECT 1 FROM information_schema.tables 
                  WHERE table_catalog='DB_NAME' AND 
                        table_schema='public' AND 
                        table_name='TABLE_NAME');
    

    与直接从 pg_* 表中选择相比,使用 information_schema 的优势在于查询的某种程度的可移植性。

    【讨论】:

    • 对于默认 table_catalog 使用 ??
    【解决方案3】:
    select exists(select relname from pg_class 
    where relname = 'mytablename' and relkind='r');
    

    【讨论】:

      【解决方案4】:

      第一个答案对我不起作用。我发现成功检查了 pg_class 中的关系:

      def table_exists(con, table_str):
          exists = False
          try:
              cur = con.cursor()
              cur.execute("select exists(select relname from pg_class where relname='" + table_str + "')")
              exists = cur.fetchone()[0]
              print exists
              cur.close()
          except psycopg2.Error as e:
              print e
          return exists
      

      【讨论】:

        【解决方案5】:
        #!/usr/bin/python
        # -*- coding: utf-8 -*-
        
        import psycopg2
        import sys
        
        
        con = None
        
        try:
        
            con = psycopg2.connect(database='testdb', user='janbodnar') 
            cur = con.cursor()
            cur.execute('SELECT 1 from mytable')          
            ver = cur.fetchone()
            print ver    //здесь наш код при успехе
        
        
        except psycopg2.DatabaseError, e:
            print 'Error %s' % e    
            sys.exit(1)
        
        
        finally:
        
            if con:
                con.close()
        

        【讨论】:

          【解决方案6】:

          我知道你要求 psycopg2 答案,但我想我会添加一个基于 pandas 的实用程序函数(它在引擎盖下使用 psycopg2),只是因为 pd.read_sql_query() 让事情变得如此方便,例如避免创建/关闭游标。

          import pandas as pd
          
          def db_table_exists(conn, tablename):
              # thanks to Peter Hansen's answer for this sql
              sql = f"select * from information_schema.tables where table_name='{tablename}'" 
              
              # return results of sql query from conn as a pandas dataframe
              results_df = pd.read_sql_query(sql, conn)
          
              # True if we got any results back, False if we didn't
              return bool(len(results_df))
          

          我仍然使用 psycopg2 创建 db-connection 对象conn,类似于此处的其他答案。

          【讨论】:

            【解决方案7】:

            您可以查看pg_class目录:

            目录 pg_class 目录表和大多数其他有 列或在其他方面类似于表。这包括索引(但 另见 pg_index),序列(但另见 pg_sequence),视图, 物化视图、复合类型和 TOAST 表;见relkind。 下面,当我们指的是我们所说的所有这些类型的对象时 “关系”。并非所有列对所有关系类型都有意义。

            假设以cur为光标打开连接,

            cur.execute("SELECT EXISTS(SELECT relname FROM pg_class WHERE relname = 'mytable');")
            
            if cur.fetchone()[0]:
                # if table exists, do something here
                return True
            

            cur.fetchone() 将解析为 TrueFalse,因为 EXISTS() 函数。

            【讨论】:

              【解决方案8】:

              以下解决方案也处理schema

              import psycopg2
              
              with psycopg2.connect("dbname='dbname' user='user' host='host' port='port' password='password'") as conn:
                  cur = conn.cursor()
                  query = "select to_regclass(%s)"
                  cur.execute(query, ['{}.{}'.format('schema', 'table')])
              
              exists = bool(cur.fetchone()[0])
              

              【讨论】:

                【解决方案9】:

                扩展上述 EXISTS 的使用,我需要一些东西来测试表的存在性。我发现在 select 语句上使用 fetch 测试结果会在现有的空表上产生结果“None”——不理想。

                这是我想出的:

                import psycopg2
                
                def exist_test(tabletotest):
                
                    schema=tabletotest.split('.')[0]
                    table=tabletotest.split('.')[1]
                    existtest="SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = '"+schema+"' AND table_name = '"+table+"' );"
                
                    print('existtest',existtest)
                
                    cur.execute(existtest) # assumes youve already got your connection and cursor established
                
                    # print('exists',cur.fetchall()[0])
                    return ur.fetchall()[0] # returns true/false depending on whether table exists
                
                
                exist_test('someschema.sometable')
                

                【讨论】:

                  猜你喜欢
                  • 2015-03-06
                  • 2013-12-25
                  • 2017-07-30
                  • 1970-01-01
                  • 2018-08-12
                  • 2017-02-16
                  • 2022-01-17
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多