IT TIP

MySQL : 쿼리에서 열 이름 또는 별칭 가져 오기

itqueen 2020. 12. 31. 23:13
반응형

MySQL : 쿼리에서 열 이름 또는 별칭 가져 오기


나는 SHOW COLUMNS명령을 요구하지 않습니다 .

SQL 쿼리를 지정할 수 있고 실행시 쿼리 결과를 나타내는 행과 열이있는 결과 집합을 반환하는 heidisql과 유사하게 작동하는 응용 프로그램을 만들고 싶습니다. 결과 집합의 열 이름은 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()      

cursor.description은 각각의 [0]이 열 헤더 인 튜플의 튜플을 제공합니다.

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

이것은 thefreeman과 동일하지만 목록과 사전 이해를 사용하는 파이썬 방식에 더 가깝습니다.

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

pprint.pprint(result)

@James 답변과 유사하게 더 파이썬적인 방법은 다음과 같습니다.

fields = map(lambda x:x[0], cursor.description)
result = [dict(zip(fields,row))   for row in cursor.fetchall()]

결과에 대한 맵이있는 단일 열을 얻을 수 있습니다.

extensions = map(lambda x: x['ext'], result)

또는 필터 결과 :

filter(lambda x: x['filesize'] > 1024 and x['filesize'] < 4096, result)

또는 필터링 된 열에 대한 값 누적 :

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

나는 이것이 당신이 필요로하는 일을해야한다고 생각합니다 (위의 답변을 기반으로 함). 나는 그것을 작성하는 더 비단뱀적인 방법이 있다고 확신하지만 일반적인 아이디어를 얻어야합니다.

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)

You could also use MySQLdb.cursors.DictCursor. This turns your result set into a python list of python dictionaries, although it uses a special cursor, thus technically less portable than the accepted answer. Not sure about speed. Here's the edited original code that uses this.

#!/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()  

Standard dictionary functions apply, for example, len(row[0]) to count the number of columns for the first row, list(row[0]) for a list of column names (for the first row), etc. Hope this helps!


Looks like MySQLdb doesn't actually provide a translation for that API call. The relevant C API call is mysql_fetch_fields, and there is no MySQLdb translation for that


This is only an add-on to the accepted answer:

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

where dotdict is:

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

This will allow you to access much easier the values by column names.
Suppose you have a user table with columns name and email:

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

Try:

cursor.column_names

mysql connector version:

mysql.connector.__version__
'2.2.9'

You can also do this to just get the field titles:

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

ReferenceURL : https://stackoverflow.com/questions/5010042/mysql-get-column-name-or-alias-from-query

반응형