Как выводить результаты запросов MySQL в формате CSV?

Есть ли простой способ запустить 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

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

822
задан MCS 10 дек. '08 в 18:59
источник поделиться

24 ответов

От http://www.tech-recipes.com/rx/1475/save-mysql-query-results-into-a-text-or-csv-file/

SELECT order_id,product_name,qty
FROM orders
WHERE foo = 'bar'
INTO OUTFILE '/var/lib/mysql-files/orders.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

С помощью этой команды имена столбцов не будут экспортироваться.

Также обратите внимание, что /var/lib/mysql-files/orders.csv будет на сервере, на котором запущена MySQL. Пользователь, которому запущен процесс MySQL, должен иметь права на запись в выбранный каталог или команда не работает.

Если вы хотите записать вывод на локальный компьютер с удаленного сервера (особенно с размещенной или виртуализированной машиной, такой как Heroku или Amazon RDS), это решение не подходит.

1308
ответ дан Paul Tomblin 10 дек. '08 в 19:07
источник поделиться
$ mysql your_database --password=foo < my_requests.sql > out.csv

Откроется вкладка. Труба это так, чтобы получить истинный CSV (спасибо @therefromhere):

... .sql | sed 's/\t/,/g' > out.csv
317
ответ дан Stan 08 апр. '10 в 19:53
источник поделиться

mysql --batch, -B

Печать результатов с помощью вкладки в качестве разделителя столбцов, причем каждая строка на новая линия. С помощью этой опции mysql не использует файл истории. Пакетный режим приводит к нетабулярному формату вывода и экранированию специальные символы. Экранирование может быть отключено с использованием режима raw; видеть описание опции -raw.

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

151
ответ дан serbaut 30 сент. '09 в 13:51
источник поделиться

Вот довольно грубый способ сделать это. Найденный где-то, не может взять кредит

mysql --user=wibble --password wobble -B -e "select * from vehicle_categories;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > vehicle_categories.csv

Хорошо работает. Еще раз, хотя регулярное выражение доказывает только запись.


Regex Пояснение:

  • s///означает замену между первым//тем, что между вторым //
  • "g" в конце - это модификатор, который означает "все экземпляры, а не только первые"
  • ^ (в этом контексте) означает начало строки
  • $(в этом контексте) означает конец строки

Итак, все вместе:

s/'/\'/          replace ' with \'
s/\t/\",\"/g     replace all \t (tab) with ","
s/^/\"/          at the beginning of the line place a "
s/$/\"/          at the end of the line place a "
s/\n//g          replace all \n (newline) with nothing
100
ответ дан Tim Harding 22 марта '11 в 20:31
источник поделиться

Unix/Cygwin, пропустите его через 'tr':

mysql <database> -e "<query here>" | tr '\t' ',' > data.csv

N.B.: В нем не используются ни встроенные запятые, ни встроенные вкладки.

55
ответ дан strickli 11 окт. '12 в 18:19
источник поделиться

Решение OUTFILE, данное Paul Tomblin, заставляет файл записываться на сервере MySQL, поэтому это будет работать, только если у вас есть FILE, а также доступ к логину или другие средства для извлечения файла из этого поля.

Если у вас нет такого доступа, а вывод с разделителями-табуляторами является разумной заменой CSV (например, если конечная цель заключается в том, чтобы импортировать в Excel), то решение Serbaut (используя mysql --batch и необязательно --raw) - это путь.

30
ответ дан Leland Woodbury 22 июня '10 в 16:48
источник поделиться

Как насчет:

mysql your_database -p < my_requests.sql | awk '{print $1","$2}' > out.csv
26
ответ дан Steve 10 нояб. '11 в 21:41
источник поделиться

MySQL Workbench может экспортировать наборы записей в CSV, и, похоже, очень хорошо обрабатывает запятые в полях. CSV открывается в OpenOffice отлично.

24
ответ дан David Oliver 26 июня '12 в 20:15
источник поделиться

Все решения на сегодняшний день, за исключением Mysql workbench one, являются неправильными и, возможно, небезопасными (например, проблемами безопасности), по крайней мере, для некоторого возможного содержимого в mysql db.

Mysql Workbench (и аналогично PHPMyAdmin) предоставляют формально правильное решение, но предназначены для загрузки вывода в пользовательское местоположение. Они не так полезны для таких вещей, как автоматизация экспорта данных.

Невозможно создать достоверно корректный csv из вывода mysql -B -e 'SELECT ...', поскольку он не может кодировать возврат каретки и пробел в полях. Флаг '-s' для mysql делает обратное сбрасывание и может привести к правильному решению. Однако использование языка сценариев (один с достойными внутренними структурами данных, а не bash), и библиотеки, в которых проблемы с кодировкой уже были тщательно разработаны, намного безопаснее.

Я подумал о написании script для этого, но как только я подумал о том, что бы я назвал, мне пришло в голову поиск ранее существовавшей работы с тем же именем. В то время как я не перешел на это полностью, решение в https://github.com/robmiller/mysql2csv выглядит многообещающим. В зависимости от вашего приложения подход yaml для указания команд SQL может или не понравится. Я также не в восторге от необходимости в более новой версии рубинов, чем стандартно с моим ноутбуком Ubuntu 12.04 или сервером Squeeze Debian. Да, я знаю, что могу использовать RVM, но я бы предпочел не поддерживать это с такой простой целью.

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

20
ответ дан mc0e 11 окт. '13 в 8:04
источник поделиться

Это спасло меня пару раз. Быстро и работает!

- пакет

- raw

Пример:

sudo mysql -udemo_user -p -h127.0.0.1 --port=3306 \
   --default-character-set=utf8 --database=demo_database \
   --batch --raw < /var/demo_sql_query.sql > /var/demo_csv_export.csv
16
ответ дан hrvoj3e 29 янв. '16 в 16:52
источник поделиться

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

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

15
ответ дан Murthy Upadhyayula 25 июня '15 в 9:50
источник поделиться
  • логика:

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

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

8
ответ дан zloctb 07 мая '14 в 11:41
источник поделиться

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

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

from your_table where etc;

Пояснение:

  • Заменить "с" "в каждом поле → заменить (поле1, '" ', '""')
  • Обведите каждый результат кавычками → concat ('"', result1, '' ')
  • Поместите запятую между каждым цитируемым результатом → concat_ws (',', quoted1, quoted2,...)

Что это!

7
ответ дан Marty Hirsch 06 дек. '11 в 21:50
источник поделиться

Многие ответы на этой странице слабы, потому что они не обрабатывают общий случай того, что может произойти в формате 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

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

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

7
ответ дан Chris Johnson 01 февр. '16 в 8:52
источник поделиться

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

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

6
ответ дан Jonathan 11 дек. '08 в 2:34
источник поделиться

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

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    
6
ответ дан johntellsall 23 окт. '14 в 19:09
источник поделиться

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

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

Perl script (снайпер из другого места) делает хорошую работу по преобразованию полей, расположенных на вкладке, в CSV.

4
ответ дан extraplanetary 07 июля '11 в 20:34
источник поделиться

Не точно как формат CSV, но tee команда из MySQL клиент может использоваться для сохранения вывод в файл локальный:

tee foobar.txt
SELECT foo FROM bar;

Вы можете отключить его, используя notee.

Проблема с SELECT … INTO OUTFILE …; заключается в том, что для этого требуется разрешение на запись файлов на сервер.

3
ответ дан Denilson Sá Maia 29 мая '14 в 21:14
источник поделиться

Основываясь на 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);

?>
3
ответ дан Michael Cole 29 мая '15 в 21:36
источник поделиться

Используя решение, отправленное Tim, я создал этот bash script, чтобы облегчить процесс (запрошен пароль root, но вы можете легко изменить script для запроса любого другого пользователя):

#!/bin/bash

if [ "$1" == "" ];then
    echo "Usage: $0 DATABASE TABLE [MYSQL EXTRA COMMANDS]"
    exit
fi

DBNAME=$1
TABLE=$2
FNAME=$1.$2.csv
MCOMM=$3

echo "MySQL password:"
stty -echo
read PASS
stty echo

mysql -uroot -p$PASS $MCOMM $DBNAME -B -e "SELECT * FROM $TABLE;" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > $FNAME

Он создаст файл с именем: database.table.csv

2
ответ дан lepe 16 мая '13 в 11:04
источник поделиться

В этом ответе используется 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 isn't much better, but this is an example
# http://stackoverflow.com/questions/12461484/is-it-secure-to-store-passwords-as-environment-variables-rather-than-as-plain-t
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)
2
ответ дан Ben 25 янв. '17 в 2:02
источник поделиться
Try this code:
SELECT 'Column1', 'Column2', 'Column3', 'Column4', 'Column5'
UNION ALL
SELECT column1, column2,
column3 , column4, column5 FROM demo
INTO OUTFILE '/tmp/demo.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';

for more: http://dev.mysql.com/doc/refman/5.1/en/select-into.html
1
ответ дан Indrajeet Singh 08 сент. '14 в 15:06
источник поделиться

Если на компьютере, который вы используете, установлен PHP, вы можете написать PHP script для этого. Для установки PHP требуется расширение MySQL.

Вы можете вызвать интерпретатор PHP из командной строки следующим образом:

php --php-ini path/to/php.ini your-script.php

Я включаю переключатель --php-ini, потому что вам может понадобиться использовать собственную конфигурацию PHP, которая позволяет расширение MySQL. На PHP 5.3.0+ это расширение включено по умолчанию, поэтому больше нет необходимости использовать конфигурацию для его включения.

Затем вы можете написать свой экспорт script, как и любой обычный PHP скрипт:

<?php
    #mysql_connect("localhost", "username", "password") or die(mysql_error());
    mysql_select_db("mydb") or die(mysql_error());

    $result = mysql_query("SELECT * FROM table_with_the_data p WHERE p.type = $typeiwant");

    $result || die(mysql_error());

    while($row = mysql_fetch_row($result)) {
      $comma = false;
      foreach ($row as $item) {

        # Make it comma separated
        if ($comma) {
          echo ',';
        } else {
          $comma = true;
        }

        # Quote the quotes
        $quoted = str_replace("\"", "\"\"", $item);

        # Quote the string
        echo "\"$quoted\"";
      }
        echo "\n";
    }
?>

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

0
ответ дан user7610 17 марта '12 в 11:46
источник поделиться

Я использую [SQLyog] (webyog.com/product/sqlyog) для экспорта в csv. Это довольно легко.

Вот несколько ссылок на него: http://sqlyogkb.webyog.com/article/215-export-data

Результат запроса запроса sqlyog как csv

0
ответ дан Veer Abheek Singh Manhas 05 дек. '17 в 4:20
поделиться

Другие вопросы по меткам