Используя python для записи запроса mysql в csv, необходимо показать имена полей

У меня есть следующее:

import MySQLdb as dbapi
import sys
import csv

dbServer='localhost'
dbPass='supersecretpassword'
dbSchema='dbTest'
dbUser='root'

dbQuery='SELECT * FROM pbTest.Orders;'

db=dbapi.connect(host=dbServer,user=dbUser,passwd=dbPass)
cur=db.cursor()
cur.execute(dbQuery)
result=cur.fetchall()

c = csv.writer(open("temp.csv","wb"))
c.writerow(result)

Это производит искаженный беспорядок. Я знаком с использованием печати записи [0] и т. д. Не знаю, как мне настроить форматирование. чтобы создать что-то вроде запроса в консоли. Я не могу выполнить простой INTO OUTFILE с сервера mysql.


Обновить

Прошло 8 лет; Я все еще получаю случайные обновления или запросы по этому вопросу.

Как указано в некоторых комментариях, cursor.description из DBAPI - это то, что я искал.

Вот более современный пример в Python 3, использующий драйвер pymysql для подключения к MariaDB, который выберет и извлечет все строки в кортеж, заголовки/описание строк в список. Затем я объединяю эти две структуры данных в один список, который записывается в CSV-файл.

С именами заголовков, являющимися первой записью в списке результатов; запись результата в файл линейным способом гарантирует, что заголовок строки будет первой строкой в ​​файле CSV.

import pymysql
import csv
import sys

db_opts = {
    'user': 'A',
    'password': 'C',
    'host': 'C',
    'database': 'D'
}

db = pymysql.connect(**db_opts)
cur = db.cursor()

sql = 'SELECT * from schema_name.table_name where id=123'
csv_file_path = '/tmp/my_csv_file.csv'

try:
    cur.execute(sql)
    rows = cur.fetchall()
finally:
    db.close()

# Continue only if there are rows returned.
if rows:
    # New empty list called 'result'. This will be written to a file.
    result = list()

    # The row name is the first entry for each entity in the description tuple.
    column_names = list()
    for i in cur.description:
        column_names.append(i[0])

    result.append(column_names)
    for row in rows:
        result.append(row)

    # Write result to file.
    with open(csv_file_path, 'w', newline='') as csvfile:
        csvwriter = csv.writer(csvfile, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
        for row in result:
            csvwriter.writerow(row)
else:
    sys.exit("No rows found for query: {}".format(sql))

person Mathnode    schedule 06.01.2011    source источник


Ответы (6)


Вы можете вывести все результаты в файл csv без зацикливания:

rows = cursor.fetchall()
fp = open('/tmp/file.csv', 'w')
myFile = csv.writer(fp)
myFile.writerows(rows)
fp.close()
person jwhat    schedule 30.07.2012
comment
Отличный ответ. Я бы просто изменил переменную «файл» на что-то вроде myfile, поскольку «файл» — это ключевое слово. - person Will; 06.03.2014
comment
Это прекрасно работает, но в любом случае я могу получить имена полей/столбцов, пожалуйста. - person Jake Wagner; 28.03.2017
comment
Спасибо, нашел это очень удобным. - person Helen Neely; 10.04.2017
comment
@JakeWagner добавьте writer.writeheader() перед writerows() - person AK91; 11.10.2019
comment
мой csv отображается неправильно. он не заполняет ячейку только прямыми линиями - person Foggy Minded Greenhorn; 03.06.2020

result — это список строк. Итак, вам нужно будет пройтись по этому списку и написать каждую строку:

for row in result:
    c.writerow(row)
person Daniel Roseman    schedule 06.01.2011
comment
это большое спасибо, есть идеи, как я тоже могу написать имена полей? - person Mathnode; 06.01.2011
comment
@teatime — вы можете получить имена полей из result[0].keys (или, что то же самое, row.keys. - person mtrw; 06.01.2011
comment
К сожалению, этот ответ не полностью отвечает на заголовок вопроса (необходимо показать имена полей). Комментарий @mtrw помогает, но неприменим к данному коду (объект кортежа не имеет атрибута «ключи»). Это могло бы быть применимо, если бы курсор был курсором словаря, т.е. созданным с использованием dbconn.cursor(dictionary=True). - person LarsH; 17.04.2015
comment
При использовании курсора словаря result[0].keys() дает список имен столбцов. Однако это (обычно) не в том порядке, который вы получили бы от result[0] для курсора, не являющегося словарем, и не в том же порядке, что вы видели бы в клиенте MySQL. Короче, бардак. Если порядок столбцов не имеет значения, это может быть нормально. - person LarsH; 18.04.2015

Ответьте с именами заголовков столбцов для всех, кто сталкивается с этим: (я использую метод Jwhat для записи в csv)

result = cur.fetchall()

#Getting Field Header names
column_names = [i[0] for i in cur.description]
fp = open('Result_Set.csv' 'w')
myFile = csv.writer(fp, lineterminator = '\n') #use lineterminator for windows
myFile.writerow(column_names)
myFile.writerows(result)
fp.close()
person Mwspencer    schedule 14.12.2017

Предыдущий ответ дал бы ошибку. Сначала в файл должен быть записан заголовок, а затем добавлены строки. Следующее сработало для меня.

rows = cursor.fetchall()
headers = [col[0] for col in cursor.description] # get headers
rows = (tuple(headers),) + rows # add headers to rows
fp = open('/tmp/file.csv', 'w')
myFile = csv.writer(fp)
myFile.writerow(headers)
myFile.writerows(rows)
fp.close()
person George B    schedule 13.07.2018
comment
Почему вы добавляете заголовок и строки? Это запишет заголовки дважды. - person Rahul; 28.04.2020

Просто добавьте еще одну вещь в ответ @jwhat.

Если вы собираетесь открыть этот CSV-файл в Windows, вам нужно будет обработать лишние пустые строки.

просто измените код на следующий, так как терминатор строки по умолчанию в 2.7 - это \r\n

myFile = csv.writer(fp, lineterminator='\n')
person HappyBambi    schedule 10.05.2016
comment
Благодарю вас! Я открывал Excel и удалял оттуда пустые строки, и это всегда было больно, и я так и не понял, как это остановить. - person Mwspencer; 15.12.2017

Я немного знаком с python, но после небольшого поиска в Google, следует ли вам использовать writerows (с S), который записывает несколько строк, а не writerow, который ожидает одну строку.

Как я уже сказал, это что-то вроде удара в темноте от меня.

person Jaydee    schedule 06.01.2011