【问题标题】:MySQL: Get column name or alias from queryMySQL:从查询中获取列名或别名
【发布时间】:2011-06-27 23:00:22
【问题描述】:

我不是要SHOW COLUMNS 命令。

我想创建一个与 heidisql 工作类似的应用程序,您可以在其中指定 SQL 查询,并在执行时返回一个结果集,其中包含代表查询结果的行和列。结果集中的列名应与您在 SQL 查询中定义的所选列相匹配。

在我的 Python 程序(使用MySQLdb)中,我的查询只返回行和列结果,而不是列名。在以下示例中,列名将是 exttotalsizefilecount。 SQL 最终将在程序之外。

我能想到的唯一方法是编写我自己的 SQL 解析器逻辑来提取选定的列名。

有没有一种简单的方法来获取所提供 SQL 的列名? 接下来我需要知道查询返回了多少列?

# Python

import MySQLdb

#===================================================================
# connect to mysql
#===================================================================

try:
    db = MySQLdb.connect(host="myhost", user="myuser", passwd="mypass",db="mydb")
except MySQLdb.Error, e:
    print "Error %d: %s" % (e.args[0], e.args[1])
    sys.exit (1)

#===================================================================
# query select from table
#===================================================================

cursor = db.cursor ()   

cursor.execute ("""\
     select ext,
        sum(size) as totalsize,
        count(*) as filecount
     from fileindex
    group by ext
    order by totalsize desc;
""")

while (1):
    row = cursor.fetchone ()
    if row == None:
        break
    print "%s %s %s\n" % (row[0], row[1], row[2])

cursor.close()
db.close()      

【问题讨论】:

  • cursor.column_names

标签: python mysql mysql-python


【解决方案1】:

看起来 MySQLdb 实际上并没有为该 API 调用提供翻译。相关的 C API 调用是mysql_fetch_fieldsthere is no MySQLdb translation for that

【讨论】:

    【解决方案2】:

    cursor.description 会给你一个元组的元组,其中每个 [0] 是列标题。

    num_fields = len(cursor.description)
    field_names = [i[0] for i in cursor.description]
    

    【讨论】:

    • cursor.column_names 也可以
    • 在 MySQLdb 1.2.5 中 cursor.column_names 缺失。
    • @YaroslavNikitenko .column_names 不见了?我需要使用 .description 来获取列名吗?
    • @SteveS 从我去年写的看来:)
    【解决方案3】:

    我认为这应该满足您的需求(基于上述答案)。我确信有一种更 Pythony 的方式来编写它,但你应该明白一般的想法。

    cursor.execute(query)
    columns = cursor.description
    result = []
    for value in cursor.fetchall():
        tmp = {}
        for (index,column) in enumerate(value):
            tmp[columns[index][0]] = column
        result.append(tmp)
    pprint.pprint(result)
    

    【讨论】:

    • 还有其他简单的方法,为什么不带字段返回值?
    【解决方案4】:

    这与 thefreeman 相同,但更多的是使用列表和字典理解的 Python 方式

    columns = cursor.description 
    result = [{columns[index][0]:column for index, column in enumerate(value)} for value in cursor.fetchall()]
    
    pprint.pprint(result)
    

    【讨论】:

      【解决方案5】:

      类似于@James 的回答,更 Python 的方式可以是:

      fields = [field_md[0] for field_md in cursor.description]
      result = [dict(zip(fields,row)) for row in cursor.fetchall()]
      

      您可以在结果上获得带有列表理解的单列:

      extensions = [row['ext'] for row in result)
      

      或在列表推导中使用附加的 if 过滤结果:

      large = [row for row in result if row['filesize'] > 1024 and row['filesize'] < 4096]
      

      或累积过滤列的值:

      totalTxtSize = reduce(
              lambda x,y: x+y,
              filter(lambda x: x['ext'].lower() == 'txt', result)
      )
      

      【讨论】:

      • 彻底。使用 fetchall 比在游标上迭代有优势吗?
      • @kzarns:我想说的是使示例更短,并获得完整列表。您可以创建一个生成器函数,而不是使用 yield 迭代光标,并且可能会使用更少的内存。
      • 不适用于我,只有第一行被转换,稍微适应使其工作:fields = [i[0] for i in cursor.description] 然后result = [dict(zip(fields,row)) for row in cursor.fetchall()] 将工作
      【解决方案6】:

      您也可以使用MySQLdb.cursors.DictCursor。这会将您的结果集转换为 python 字典的 python 列表,尽管它使用特殊的游标,因此在技术上比公认的答案更不便携。不确定速度。这是使用它的经过编辑的原始代码。

      #!/usr/bin/python -u
      
      import MySQLdb
      import MySQLdb.cursors
      
      #===================================================================
      # connect to mysql
      #===================================================================
      
      try:
          db = MySQLdb.connect(host='myhost', user='myuser', passwd='mypass', db='mydb', cursorclass=MySQLdb.cursors.DictCursor)
      except MySQLdb.Error, e:
          print 'Error %d: %s' % (e.args[0], e.args[1])
          sys.exit(1)
      
      #===================================================================
      # query select from table
      #===================================================================
      
      cursor = db.cursor()
      
      sql = 'SELECT ext, SUM(size) AS totalsize, COUNT(*) AS filecount FROM fileindex GROUP BY ext ORDER BY totalsize DESC;'
      
      cursor.execute(sql)
      all_rows = cursor.fetchall()
      
      print len(all_rows) # How many rows are returned.
      for row in all_rows: # While loops always make me shudder!
          print '%s %s %s\n' % (row['ext'], row['totalsize'], row['filecount'])
      
      cursor.close()
      db.close()  
      

      应用标准字典函数,例如,len(row[0]) 用于计算第一行的列数,list(row[0]) 用于列名列表(第一行)等。希望这会有所帮助!

      【讨论】:

      【解决方案7】:

      这只是对已接受答案的补充:

      def get_results(db_cursor):
          desc = [d[0] for d in db_cursor.description]
          results = [dotdict(dict(zip(desc, res))) for res in db_cursor.fetchall()]
          return results
      

      dotdict 在哪里:

      class dotdict(dict):
          __getattr__ = dict.get
          __setattr__ = dict.__setitem__
          __delattr__ = dict.__delitem__
      

      这将使您可以更轻松地按列名访问值。
      假设您有一个 user 表,其中包含 nameemail 列:

      cursor.execute('select * from users')
      results = get_results(cursor)
      for res in results:
        print(res.name, res.email)
      

      【讨论】:

        【解决方案8】:

        试试:

        cursor.column_names
        

        mysql 连接器版本:

        mysql.connector.__version__
        '2.2.9'
        

        【讨论】:

          【解决方案9】:

          您也可以这样做来获取字段标题:

          table = cursor.description
          check = 0
          for fields in table:
              for name in fields:
                  if check < 1:
                      print(name),
                  check +=1
              check =0
          

          【讨论】:

          • 非常好的主意,谢谢!我真的很想通过查询来获取列,您的建议提供了一个很好的方法&lt;cursor&gt;.execute('describe &lt;table&gt;') 然后获取
          【解决方案10】:

          类似于建议的解决方案,只有结果是带有column_header : vaule 的json 用于db_querysql

          cur = conn.cursor()
          cur.execute(sql)
          res = [dict((cur.description[i][0], value) for i, value in enumerate(row)) for row in cur.fetchall()]
          

          输出json示例:

          [
             {
                "FIRST_ROW":"Test 11",
                "SECOND_ROW":"Test 12",
                "THIRD_ROW":"Test 13"
             },
             {
                "FIRST_ROW":"Test 21",
                "SECOND_ROW":"Test 22",
                "THIRD_ROW":"Test 23"
             }
          ]
          

          【讨论】:

            【解决方案11】:

            column_names = cursor.field_names

            【讨论】:

              猜你喜欢
              • 2021-11-25
              • 1970-01-01
              • 2011-05-09
              • 1970-01-01
              • 2013-08-20
              • 1970-01-01
              相关资源
              最近更新 更多