Как вывести результаты запроса MySQL в формате CSV? - PullRequest
1050 голосов
/ 10 декабря 2008

Есть ли простой способ выполнить запрос MySQL из командной строки Linux и вывести результаты в формате CSV ?

Вот что я сейчас делаю:

mysql -u uid -ppwd -D dbname << EOQ | sed -e 's/        /,/g' | tee list.csv
select id, concat("\"",name,"\"") as name
from students
EOQ

Это становится грязным, когда есть много столбцов, которые должны быть заключены в кавычки, или если в результатах есть кавычки, которые нужно экранировать.

Ответы [ 29 ]

22 голосов
/ 25 июня 2015

Из вашей командной строки, Вы можете сделать это:

mysql -h *hostname* -P *port number* --database=*database_name* -u *username* -p -e *your SQL query* | sed 's/\t/","/g;s/^/"/;s/$/"/;s/\n//g' > *output_file_name.csv*

Кредиты: Экспорт таблицы из Amazon RDS в файл CSV

19 голосов
/ 01 февраля 2016

Многие ответы на этой странице являются слабыми, потому что они не обрабатывают общий случай того, что может происходить в формате CSV. например запятые и кавычки, встроенные в поля и другие условия, которые всегда появляются в конце концов. Нам нужно общее решение, которое работает для всех допустимых входных данных CSV.

Вот простое и сильное решение в Python:

#!/usr/bin/env python

import csv
import sys

tab_in = csv.reader(sys.stdin, dialect=csv.excel_tab)
comma_out = csv.writer(sys.stdout, dialect=csv.excel)

for row in tab_in:
    comma_out.writerow(row)

Назовите этот файл tab2csv, поместите его в свой путь, дайте ему разрешение на выполнение, затем используйте его, перечислите это:

mysql OTHER_OPTIONS --batch --execute='select * from whatever;' | tab2csv >outfile.csv

Функции обработки CSV в Python охватывают угловые случаи для формата (ов) ввода CSV.

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

13 голосов
/ 07 мая 2014
  1. логика:

CREATE TABLE () (SELECT data FROM other_table ) ENGINE=CSV ;

При создании таблицы CSV сервер создает файл формата таблицы в каталог базы данных. Файл начинается с имени таблицы и имеет расширение .frm. Механизм хранения также создает файл данных. Его имя начинается с имени таблицы и имеет расширение .CSV. Файл данных простой текстовый файл. Когда вы храните данные в таблице, хранилище Движок сохраняет его в файл данных в формате значений, разделенных запятыми.

10 голосов
/ 25 января 2017

В этом ответе используется Python и популярная сторонняя библиотека, PyMySQL . Я добавляю его, потому что библиотека Python csv достаточно мощная, чтобы правильно обрабатывать множество различных вариантов .csv, и никакие другие ответы не используют код Python для взаимодействия с базой данных. *

import contextlib
import csv
import datetime
import os

# https://github.com/PyMySQL/PyMySQL
import pymysql

SQL_QUERY = """
SELECT * FROM my_table WHERE my_attribute = 'my_attribute';
"""

# embedding passwords in code gets nasty when you use version control
# the environment is not much better, but this is an example
# https://stackoverflow.com/questions/12461484
SQL_USER = os.environ['SQL_USER']
SQL_PASS = os.environ['SQL_PASS']

connection = pymysql.connect(host='localhost',
                             user=SQL_USER,
                             password=SQL_PASS,
                             db='dbname')

with contextlib.closing(connection):
    with connection.cursor() as cursor:
        cursor.execute(SQL_QUERY)
        # Hope you have enough memory :)
        results = cursor.fetchall()

output_file = 'my_query-{}.csv'.format(datetime.datetime.today().strftime('%Y-%m-%d'))
with open(output_file, 'w', newline='') as csvfile:
    # http://stackoverflow.com/a/17725590/2958070 about lineterminator
    csv_writer = csv.writer(csvfile, lineterminator='\n')
    csv_writer.writerows(results)
10 голосов
/ 06 декабря 2011

Это просто и работает на чем угодно, не требуя пакетного режима или выходных файлов:

select concat_ws(',',
    concat('"', replace(field1, '"', '""'), '"'),
    concat('"', replace(field2, '"', '""'), '"'),
    concat('"', replace(field3, '"', '""'), '"'))

from your_table where etc;

Пояснение:

  1. Заменить "на" "в каждом поле -> заменить (field1, '", "" "')
  2. Заключите каждый результат в кавычки -> concat ('"', result1, '"')
  3. Поместите запятую между каждым указанным результатом -> concat_ws (',', quoted1, quoted2, ...)

Вот и все!

9 голосов
/ 11 декабря 2008

В качестве альтернативы ответу выше, у вас может быть таблица MySQL, использующая механизм CSV.

Тогда у вас будет файл на жестком диске, который всегда будет в формате CSV, который вы можете просто скопировать без обработки.

8 голосов
/ 23 октября 2014

Чтобы развернуть предыдущие ответы, следующая однострочная строка экспортирует одну таблицу в виде файла, разделенного табуляцией. Это подходит для автоматизации, экспорт базы данных каждый день или около того.

mysql -B -D mydatabase -e 'select * from mytable'

Для удобства мы можем использовать одну и ту же технику для вывода списка таблиц MySQL и описания полей в одной таблице:

mysql -B -D mydatabase -e 'show tables'

mysql -B -D mydatabase -e 'desc users'

Field   Type    Null    Key Default Extra
id  int(11) NO  PRI NULL    auto_increment
email   varchar(128)    NO  UNI NULL    
lastName    varchar(100)    YES     NULL    
title   varchar(128)    YES UNI NULL    
userName    varchar(128)    YES UNI NULL    
firstName   varchar(100)    YES     NULL    
7 голосов
/ 13 января 2018

Также, если вы выполняете запрос в командной строке Bash, я считаю, что команду tr можно использовать для замены вкладок по умолчанию на произвольные разделители.

$ echo "SELECT * FROM Table123" | mysql Database456 | tr "\t" ,

6 голосов
/ 29 мая 2015

Опираясь на user7610, вот лучший способ сделать это. С mysql outfile было 60 минут проблем с владением файлами и перезаписью.

Это не круто, но сработало за 5 минут.

php csvdump.php localhost root password database tablename > whatever-you-like.csv

<?php

$server = $argv[1];
$user = $argv[2];
$password = $argv[3];
$db = $argv[4];
$table = $argv[5];

mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db($db) or die(mysql_error());

// fetch the data
$rows = mysql_query('SELECT * FROM ' . $table);
$rows || die(mysql_error());


// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');

// output the column headings

$fields = [];
for($i = 0; $i < mysql_num_fields($rows); $i++) {
    $field_info = mysql_fetch_field($rows, $i);
    $fields[] = $field_info->name;
}
fputcsv($output, $fields);

// loop over the rows, outputting them
while ($row = mysql_fetch_assoc($rows)) fputcsv($output, $row);

?>
5 голосов
/ 07 июля 2011

Вот что я делаю:

echo $QUERY | \
  mysql -B  $MYSQL_OPTS | \
  perl -F"\t" -lane 'print join ",", map {s/"/""/g; /^[\d.]+$/ ? $_ : qq("$_")} @F ' | \
  mail -s 'report' person@address

Скрипт perl (снятый откуда-то) отлично справляется с преобразованием полей с табуляцией в CSV.

...