93

SHOW COLUMNS命令を求めているわけではありません。

Heidisql と同様に機能するアプリケーションを作成したいと考えています。このアプリケーションでは、SQL クエリを指定でき、実行すると、クエリ結果を表す行と列を含む結果セットが返されます。結果セットの列名は、SQL クエリで定義されているように、選択した列と一致する必要があります。

私の Python プログラム (を使用MySQLdb) では、クエリは行と列の結果のみを返しますが、列名は返しません。次の例では、列名は 、、extおよびtotalsizeになりfilecountます。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()      
4

11 に答える 11

253

cursor.description は、それぞれの [0] が列ヘッダーであるタプルのタプルを提供します。

num_fields = len(cursor.description)
field_names = [i[0] for i in cursor.description]
于 2011-02-20T18:13:48.290 に答える
37

これは thefreeman と同じですが、リストと辞書内包表記を使用したより Python 的な方法です。

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

pprint.pprint(result)
于 2013-02-23T19:23:03.433 に答える
24

@Jamesの回答と同様に、よりpythonicな方法は次のとおりです。

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)
)
于 2013-07-08T18:59:35.667 に答える
12

これは必要なことを行うべきだと思います(上記の回答に基づいています)。私はそれを書くためのより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)
于 2012-12-25T05:15:35.247 に答える
8

を使用することもできます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])列名のリスト (最初の行の) などに適用されます。

于 2016-11-01T22:56:17.803 に答える
2

MySQLdb は実際にはその API 呼び出しの翻訳を提供していないようです。関連する C API 呼び出しはmysql_fetch_fieldsであり、そのための MySQLdb 変換はありません

于 2011-02-15T22:09:54.950 に答える