Как вывести результаты запроса 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

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

Вы можете использовать REPLACE() в своем запросе, чтобы экранировать кавычки.

dsm 10.12.2008 19:08

Посмотрите мой ответ в [this stackoverflow] [1] [1]: stackoverflow.com/questions/12242772/…

biniam 01.04.2015 19:14

Принятый ответ на этот вопрос о переполнении стека, вероятно, лучший способ: stackoverflow.com/questions/3760631/mysql-delimiter-question

Samuel Åslund 22.01.2016 19:28

Я написал запрос функции на трекере ошибок MariaDB (jira.mariadb.org/browse/MDEV-12879). Вы можете проголосовать за него.

Jared Beck 23.05.2017 21:27
stackoverflow.com/questions/1119312/…
Sunil Rajput 05.06.2017 14:27

Скопировано из удаленного ответа ниже: SELECT @@GLOBAL.secure_file_priv; покажет вам путь, к которому у вас есть доступ. У меня не было доступа на запись к /tmp/, но у меня был доступ к /var/lib/mysql-files/.

Chloe 19.12.2018 21:33

Возможный ответ, если у вас нет доступа на запись на сервере: 1) Используйте mysqldump для дампа таблицы. 2) Импортируйте таблицу в вашу локальную базу данных. 3) Используйте принятый ответ для экспорта (select ... into outfile) в CSV.

Chloe 19.12.2018 22:04

Я предполагаю, что вы имеете в виду без программного кода, верно?

LongChalk 13.02.2020 17:06
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1 274
9
1 316 977
38
Перейти к ответу Данный вопрос помечен как решенный

Ответы 38

Ответ принят как подходящий

От 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), это решение не подходит.

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

Paul Tomblin 22.10.2011 16:32

@Tomas, если у вас есть доступ к удаленной файловой системе и MySQL, вы должны иметь возможность писать где-нибудь. вместо / tmp попробуйте /home/yourusername/file.csv - если это не удается, а набор результатов не такой большой, вы можете скопировать вывод из вашего SSH-клиента и вставить его на свой локальный компьютер.

Michael Butler 09.03.2012 19:40

К сожалению, это никоим образом не соответствует стандартам

user694971 11.07.2012 17:00

В вопросе указан MySQL, а не "совместимый со стандартами".

Paul Tomblin 11.07.2012 17:28

Как включить заголовок?

Bogdan Gusiev 25.01.2013 14:01

На компьютере с Windows строка OUTFILE должна избегать обратной косой черты. Например, я использовал строку 'C:\\wamp\\bin\\mysql\\mysql5.5.24\\bin\\output\\orders.csv'

styfle 18.02.2013 23:43

@BogdanGusiev, вы можете включить заголовок, добавив "SELECT 'order_id', 'product_name', 'qty' UNION" перед реальным запросом. Первый запрос выбора возвращает заголовок, второй запрос возвращает реальные данные; UNION объединяет все воедино.

petrkotek 14.06.2013 08:35

@BogdanGusiev посмотрите lifeboysays.wordpress.com/2012/06/23/…

Paul Tomblin 14.06.2013 17:35

@ Майкл Батлер: Вообще-то нет. Если вы используете Amazon RDS, Heroku или любое другое размещенное решение, вы вряд ли сможете просто писать на чужой сервер.

Ken Kinder 26.06.2013 19:12

что, если вы хотите использовать его после присоединения? ВЫБЕРИТЕ order_id, product_name, qty ИЗ заказов INTO OUTFILE '/tmp/orders.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\ n' присоедините x как x на xx.id = test.id

Daniel Adenew 17.07.2013 17:00

@Tomas: Я написал инструмент специально для этого. См. этот ответ StackOverflow.

spiffytech 28.07.2013 20:19

Администраторам БД следует хорошенько подумать, прежде чем предоставлять разрешение File_priv, необходимое для работы этого подхода. См. docs.oracle.com/cd/E17952_01/refman-5.0-en/…

mc0e 10.10.2013 12:19

@TMS, для этого еще нужна привилегия "предоставить файл", см. Также stackoverflow.com/questions/6091427/…

Klaas van Schelven 25.03.2014 17:24

Если у вас много столбцов и они все нужны: SELECT column_name FROM information_schema.columns WHERE table_name = 'orders' INTO OUTFILE '/tmp/orders_columns.csv' FIELDS TERMINATED BY '' ENCLOSED BY '"' LINES TERMINATED BY ',';

Dan Sandland 29.12.2014 21:22

вы можете использовать опцию экспорта myadmin для файла csv

cijagani 05.08.2015 06:15

В Windows расположение файла xampp: C: \ xampp \ mysql \ data \ <databasename> _ <month> \ orders.csv (INTO OUTFILE 'urls1.csv')

Mukesh 18.08.2015 14:24

Не забывайте о разрешениях. Мне пришлось поместить свой файл Outfile в / tmp. mysql не имеет прав на запись в мой рабочий каталог. Вот мой запрос> выберите * из daily_reads, где DeviceID = 80632679 и LoadDateLocal> '2015-06-01 00:00:00', в поля outfile '/tmp/80632679_reads_since_060115.csv', оканчивающиеся строками ',', заключенными в '' ' заканчивается '\ r \ n';

octopusgrabbus 25.08.2015 17:08

Это решение работает только тогда, когда у вас есть доступ к файловой системе сервера MYSQL, то есть у вас есть прямой административный доступ к этому серверу (и вы не против заполнить его диск экспортируемыми данными). Это не решение, если у пользователя нет доступа к серверу, например. пользователь не является администратором, или пользователь является администратором, но база данных работает удаленно, например. в AWS.

Chris Johnson 31.01.2016 22:39

Я не думаю, что это хорошо работает, если в ваших записях есть разрывы строк или двойные кавычки ... Кажется, не существует способа заменить "на" "(который, как мне кажется, является обычным в CSV) в выводе без также экранирование разрывов строк.

runamok 17.08.2016 09:09

@styfle, ну, в Windows вы можете попробовать / в качестве разделителя, например 'C:/wamp/bin/mysql/mysql5.5.24/bin/output/orders.csv', у меня это работает.

LancelotHolmes 29.10.2016 09:48

Имейте в виду, что если у вас строгие настройки, вы можете получить следующее: ОШИБКА 1290 (HY000): сервер MySQL работает с параметром --secure-file-priv, поэтому он не может выполнить этот оператор.

Kemin Zhou 03.12.2016 00:50

Если mysql работает с --secure-file-priv, вы, скорее всего, не сможете писать на /tmp. Запустите SHOW VARIABLES LIKE "secure_file_priv";, чтобы увидеть, в какой каталог вы можете писать.

Luke Moore 21.12.2016 00:32

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

user7161651 27.02.2017 17:55

@PaulTomblin, как я могу экспортировать его с именем столбца?

Pranav MS 21.08.2017 09:26

Какая польза от CSV без заголовков столбцов?

Kolob Canyon 05.09.2017 00:39

Учитывая, что OP конкретно поднимает проблемы, возникающие при цитировании, насколько этот ответ правильный? Что делать, если в одном из значений есть "?

mc0e 07.10.2017 18:59

@ mc0e Я почти уверен, что есть предложение ESCAPED BY, которое вы можете использовать, если у вас есть поля, в которых могут быть кавычки. stackoverflow.com/a/2859026/3333

Paul Tomblin 07.10.2017 21:09

@petrkotek UNION не гарантирует порядок; ваш заголовок может оказаться нижним колонтитулом

user2426679 24.09.2018 22:04

Мне пришлось использовать это для импорта в Postgres, потому что MySQL использует '\' для экранирования символов, таких как \" и \\r. \copy table (field1, field2, created_at, updated_at) from 'files/table.csv' with (format csv, header true, escape e'\\'); (я вручную вставил заголовок с помощью Notepad ++.) stackoverflow.com/questions/7484413/ddg#7495514

Chloe 19.12.2018 21:50

Каждый сервер mysql, которого я касаюсь, имеет файл с именем /var/lib/mysql-files/orders.csv, потому что каждый раз, когда мне нужно экспортировать в CSV, я копирую и вставляю из этого ответа.

brandones 22.06.2019 04:59

Ошибка выдачи: [HY000] [1290] Сервер MySQL работает с параметром --secure-file-priv, поэтому он не может выполнить этот оператор.

Dinesh Appuhami 01.08.2019 16:15

Есть ли способ создать файл только в том случае, если запрос что-то возвращает? и ничего не создавать, если количество строк = 0?

Ari 15.11.2019 14:12

@PaulTomblin Относительно того же, если я запускаю следующий запрос, я получаю сообщение об ошибке. Мой запрос: justpaste.it/2fp6f Любая помощь, спасибо.

zus 19.02.2020 08:31

Фу! Есть ли способ сделать это без отправки в файл ???

Michael 02.04.2020 22:44

@Michael попробуйте синтаксис без части INTO OUTFILE.

Paul Tomblin 03.04.2020 14:54

Я получаю ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement , не совсем понимаю, почему

Trect 28.06.2020 21:08

как заставить его добавляться в тот же файл, если мы используем итерацию / цикл.

kestrel 04.09.2020 21:40

Я создал файл csv (большой файл) и попытался загрузить его с помощью pandas. read_csv получил эту ошибку: Ошибка токенизации данных. Ошибка C: ожидалось 5 полей в строке 460308, видели 6 предложений?

Matan 13.11.2020 16:59

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

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

Каковы ограничения этого с точки зрения размера файла / записи / чтения / и т. д.?

Zach Smith 10.10.2018 11:21

mysql --batch, -B

Print results using tab as the column separator, with each row on a new line. With this option, mysql does not use the history file. Batch mode results in non-tabular output format and escaping of special characters. Escaping may be disabled by using raw mode; see the description for the --raw option.

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

это предпочтительное решение: 1) списки значений, разделенных табуляцией, распространены в UNIX 2) Импорт TSV изначально поддерживается большинством систем импорта, включая Excel, таблицы OpenOffice и т. д. 3) нет необходимости экранировать символы кавычек для текстовых полей 4 ) упрощает экспорт из командной строки

Joey T 11.12.2012 05:18

это лучшее решение, потому что, в отличие от первого, не нужно иметь разрешений на серверах, таких как RDS.

Muayyad Alsadi 13.02.2013 14:31

Изящный трюк: если вы сохраните файл с разделением табуляцией как .xls вместо .csv, он откроется в Excel без необходимости преобразования «текста в данные» и без каких-либо проблем с региональными настройками.

serbaut 12.04.2013 01:05

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

mc0e 10.10.2013 12:22

Спасибо, это мне очень поможет в будущем! CLI --help только говорит: -B, --batch: не использовать файл истории. Отключить интерактивное поведение. (Включает --silent.) Поэтому я всегда упускал из виду эту опцию, когда искал "простой" формат экспорта.

dennis 20.02.2014 12:22

Я использую это в сочетании с отличной утилитой xsv [github.com/BurntSushi/xsv] для преобразования в CSV

James 14.06.2018 08:29

у вас будет проблема с NULL .. они будут отображаться как строковые нули ..

Jonathan 10.10.2018 13:18

Вы можете пропустить заголовки столбцов, используя -N или --skip-column-names.

Flimm 20.06.2019 12:07

Я обнаружил, что --batch не экранирует символы новой строки последовательно, иногда как \n, иногда как перевод строки, за которым следует \n.

Flimm 20.06.2019 13:03
$ mysql your_database --password=foo < my_requests.sql > out.csv

Это разделено табуляцией. Подключите его вот так, чтобы получить настоящий CSV (спасибо @therefromhere):

... .sql | sed 's/\t/,/g' > out.csv

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

tmarthal 08.07.2011 06:38

Он разделен табуляцией, а не запятой.

Flimm 30.08.2011 19:13

@Flimm, при условии, что у вас нет встроенных запятых / вкладок в полях, вы можете преобразовать его, передав результат в | sed 's/\t/,/g'

John Carter 10.11.2011 08:42

Я добавил -B для хорошей оценки, но разделение табуляцией для меня так же хорошо, как и разделение запятыми.

hibbelig 16.02.2012 10:08

Довольно интересно. Почему вывод этой команды в> out.csv отличается от вывода на стандартный вывод, если не указано перенаправление файлов?

Fran Marzoa 12.08.2012 21:11

sed 'fix' не компенсирует запятые, которые могут появиться в любых выбранных данных, и будет искажать ваши столбцы, выводимые соответствующим образом

Joey T 11.12.2012 05:17

Есть ли решение для точки @ JoeyT? У меня есть запятые в некоторых полях, что, очевидно, перемещает вывод в следующий столбец

Nathan Waters 01.05.2013 12:14

@NathanWaters Да, используйте переключатель -B (пакетный), упомянутый в предыдущем решении, вместо того, чтобы изменять результаты с помощью sed.

Joey T 01.05.2013 20:44

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

mc0e 10.10.2013 12:34

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

John Hunt 30.04.2014 16:44

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

Leith 18.08.2016 08:14

sed 's / ^ / \ "/ g; s / \ t / \", \ "/ g; s / $ / \" / g'

Dr. Tyrell 20.10.2016 07:08

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

mc0e 07.10.2017 19:06

Mac OSX не поддерживает \t. Вы можете вставить литерал табуляции, используя ctrl + v, затем tab

Kirk 09.03.2018 21:18

Я не смог использовать принятый ответ, потому что получил ошибку Access denied. Это решение сработало для меня.

Niloofar 12.06.2019 15:25
| tr '\t' ',' у меня работал лучше. Сед, похоже, не подходил для этого дела.
Marcus 28.10.2019 19:26

Я получаю пустой CSV-файл. полностью пустой

Dean P 02.05.2020 00:07

Решение OUTFILE, данное Полом Томблином, вызывает запись файла на самом сервере MySQL, поэтому это будет работать, только если у вас есть доступ ФАЙЛ, а также доступ для входа в систему или другие средства для извлечения файла из этого ящика.

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

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

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

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


Объяснение регулярного выражения:

  • 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

Флаг -e был именно тем, что я искал! Спасибо!

Gaurav Gupta 03.01.2012 12:46

Это регулярное выражение на самом деле довольно просто; как и многие другие ответы на этой странице, он просто очищает вывод mysql -B. Если вы разделите регулярное выражение на отдельные операторы в отдельных строках, это будет довольно просто (для тех, кто знает регулярные выражения), для понимания.

Mei 09.03.2012 04:58

Отлично работает! Важно сказать, что заголовки уже включены (никаких дополнительных действий не требуется).

lepe 16.05.2013 12:00

На первый взгляд, это выглядит довольно сломанным. Табуляция и возврат каретки в содержимом будут неправильно обработаны. "s / '/ \' /;" вообще ничего не делает, потому что двойные кавычки в команде оболочки используют обратную косую черту. Многие другие похожие ошибки с обратной косой чертой теряются. Нет обработки обратной косой черты в поле db.

mc0e 10.10.2013 12:26

Похоже, эта команда хорошо работает в Linux, но не в Mac

Hemerson Varela 03.04.2014 23:36

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

aidan 14.04.2014 07:59

Предлагаю это ... | sed 's / "/ \" / g' | sed "s / '/ \' /; s / \ t / \", \ "/ g; s / ^ / \" /; s / $ / \ "/; s / \ n // g" ...

snowindy 26.09.2015 13:51

это на самом деле намного лучше и быстрее в некоторых случаях, чем внутренний экспорт CSV mysql. красиво сделано!

reflog 04.10.2017 13:42

Это работает, когда у меня нет прав администратора, спасибо.

Woody Sun 13.01.2020 10:48

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

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.

Это здорово. Небольшое улучшение может заключаться в цитировании всего, кроме чисел perl -F"\t" -lane 'print join ",", map {s/"/""/g; /^\d+(?:\.\d+)?$/ ? $_ : qq("$_")} @F ' - ваш не цитирует 1.2.3

artfulrobot 15.03.2017 19:00

Это должно быть общепринятым решением IMHO, конечно, с улучшением @artfulrobot.

chrisinmtown 25.09.2020 17:55

Как насчет:

mysql your_database -p < my_requests.sql | awk '{print $1","$2}' > out.csv

Мне это очень нравится. Он намного чище, и мне нравится использовать awk. Однако я бы, наверное, пошел с этим: mysql -uUser -pPassword your_database < my_requests.sql | awk 'BEGIN{OFS = " = ";} {print $1,$2}' > out.csv

Josh 11.04.2012 04:00

Это не подходит для значений полей с пробелами.

Barun Sharma 10.04.2015 09:17

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

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

from your_table where etc;

Объяснение:

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

Вот и все!

Обратите внимание, что значения NULL будут пропущены concat_ws(), что приведет к несоответствию столбцов. Чтобы этого избежать, просто используйте вместо нее пустую строку: IFNULL(field, '') (или что-то еще, что вы используете для представления NULL)

Marco Roy 22.05.2019 02:11

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

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

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

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

Затем вы можете написать свой экспортный скрипт, как любой обычный 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 или около того.

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

mc0e 10.10.2013 12:57

@ mc0e Обычно кавычки удваиваются или экранируются. Я решил удвоить кавычки, поэтому escape-символ мне не нужен. В разных программах разные представления о деталях CSV. Например, LOAD DATA в MySQL действительно обрабатывает \ как escape-символ, тогда как Open Office Calc - нет. Когда я писал ответ, я экспортировал данные в электронную таблицу.

user7610 02.11.2015 15:51

Мой код обрабатывает все, что было необходимо для экспорта набора данных мой в тот же день;) Ваш ответ также является шагом в правильном направлении, но, как говорится в первом комментарии, он должен 1) подключиться к базе данных sql из сценария напрямую как а также 2) используйте подходящую библиотеку csv.

user7610 22.10.2018 12:04

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

Спасибо большое, Дэвид. Потратив 3 часа на то, чтобы новые строки выводились правильно для HTML-содержимого в данных, я использовал MySQL Workbench и через 2 минуты у меня был готов мой CSV-файл.

mr-euro 11.07.2012 21:02

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

David Oliver 06.08.2012 01:27

Инструментальная среда mysql - лучший вариант для функции импорта и экспорта.

cijagani 05.08.2015 06:20

Хорошо, но каждый раз, когда рабочая среда ограничивает количество выбранных записей до 1000, и когда дело доходит до гораздо большего количества записей, она работает не так хорошо, то же условие для импорта часто блокируется, если я пытаюсь импортировать относительно большой файл csv в База данных mysql с помощью верстака.

LancelotHolmes 29.10.2016 09:42

Я только что успешно экспортировал более полумиллиона строк с помощью mysql workbench, поэтому большие файлы не кажутся проблемой. Вам просто нужно убедиться, что вы удалили ограничение выбора перед запуском вашего запроса, и вам также может потребоваться увеличить следующие значения в вашем файле my.ini: max_allowed_packet = 500M, net_read_timeout = 600, net_write_timeout = 600

Vincent 22.04.2018 18:47

В рабочей среде MySQL возникает неприятная утечка памяти при экспорте данных в CSV, если у вас есть большой набор данных, например, еще 1 или 2 миллиона строк, 12 ГБ ОЗУ (проверено на моей машине Linux) недостаточно, и память не очищается, если вы убить или остановить. Для большого набора данных это не решение.

Ostico 16.05.2019 18:00

Только для Unix / Cygwin, пропустите его через 'tr':

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

Примечание: при этом не обрабатываются ни встроенные запятые, ни встроенные вкладки.

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

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

как насчет встроенных символов двойных кавычек? От них тоже нужно избавиться, но я не вижу закономерности в заклинании sed для них.

chrisinmtown 25.09.2020 17:50

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

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

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

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

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

Вы правы, для сложных строк в таблице нужно использовать какую-нибудь приличную библиотеку, а не только bash. Я думаю, что у nodejs есть лучшие решения для такого рода действий. вот так пример

yeya 28.07.2016 18:28

Привет, хороший ответ, я бы добавил ссылку на решение python, предложенное ниже stackoverflow.com/a/35123787/1504300, которое работает хорошо и очень просто. Я пытался отредактировать ваше сообщение, но изменение было отклонено

reallynice 02.06.2017 15:44

Сценарий mysql2csv Роба Миллера настаивает на подключении к самой базе данных через сеть или сокет и не может использоваться в качестве конвейера в стиле Unix. Возможно, это необходимо, но это действительно ограничивает использование.

chrisinmtown 09.09.2020 22:21

@chrisinmtown, что бы вы хотели в него вложить? Может быть, вывод myslqldump? Как я уже отмечал, вывод mysql -B не может быть исправлен.

mc0e 04.10.2020 17:03

@ mc0e Я хочу передать в вывод mysqldump, прочтите это как stdin.

chrisinmtown 05.10.2020 16:20

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

mc0e 07.10.2020 07:00
  1. логика:

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

When you create a CSV table, the server creates a table format file in the database directory. The file begins with the table name and has an .frm extension. The storage engine also creates a data file. Its name begins with the table name and has a .CSV extension. The data file is a plain text file. When you store data into the table, the storage engine saves it into the data file in comma-separated values format.

Приятно, так как это правильно, никаких других настроек не требуется.

Andrew Schulman 04.01.2018 00:53

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

tee foobar.txt
SELECT foo FROM bar;

Вы можете отключить его с помощью notee.

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

Если вместо .txt используется расширение .csv, следует ли помнить о каких-либо проблемах с форматированием?

datalifenyc 09.05.2018 00:53

@myidealab Проблемы с форматированием возникают из-за того, что запятые и т. д. не экранируются. CSV - это простой текстовый формат, поэтому проблема с форматированием не возникает просто после замены расширения.

jkmartindale 20.06.2019 20:24

Попробуйте этот код:

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';

Для получения дополнительной информации: http://dev.mysql.com/doc/refman/5.1/en/select-into.html

Относитесь к тому же, если я запускаю следующий запрос, я получаю сообщение об ошибке. Мой запрос: justpaste.it/2fp6f Любая помощь, спасибо. @Indrajeet Singh

zus 19.02.2020 08: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    

Чтобы преобразовать в CSV: mysql -B -D mydatabase -e 'select * from mytable' | sed -e 's/\t/,/g'

DSimon 13.01.2015 00:15

Использование sed -e 's/\t/,/g' безопасно только в том случае, если вы уверены, что ваши данные не содержат запятых или табуляций.

awatts 20.10.2015 19:23

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

?>

Красиво, чисто и быстро работает - это отличное решение, если вы можете запускать PHP в такой среде!

John Fiala 06.04.2018 01:01

В командной строке ты можешь сделать это:

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

это один сумасшедший лайнер. шляпа

Elias Escalante 07.11.2017 05:47

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

--batchPrint results using tab as the column separator, with each row on a new line.

--rawdisables character escaping (\n, \t, \0, and \)

Пример:

mysql -udemo_user -p -h127.0.0.1 --port=3306 \
   --default-character-set=utf8mb4 --database=demo_database \
   --batch --raw < /tmp/demo_sql_query.sql > /tmp/demo_csv_export.tsv

Для полноты вы можете конвертировать в CSV (но будь осторожен, потому что вкладки могут находиться внутри значений полей - например, текстовых полей)

tr '\t' ',' < file.tsv > file.csv

Если я чего-то не упускаю, создается файл TSV, а не файл CSV ...

PressingOnAlways 12.07.2016 03:45

@PressingOnAlways Да. Цитата из документа MySQL: «Печатайте результаты, используя табуляцию в качестве разделителя столбцов, с каждой строкой на новой строке». Но при синтаксическом анализе не должно возникнуть проблем с каким-либо разделителем. Я использовал его для создания файлов Excel для своего клиента.

hrvoj3e 12.07.2016 09: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

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

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

Еще более надежным решением было бы фактическое подключение к базе данных с помощью Python, тогда вам будет легче делать то, что вам нужно сделать, чтобы иметь дело с большими наборами данных (результаты фрагментации, потоковая передача и т. д.).

Josh Rumbut 04.02.2016 18:52

@JoshRumbut, очень поздно, но я сделал stackoverflow.com/a/41840534/2958070, чтобы дополнить ваш комментарий

Ben 30.08.2019 19:28

Пожалуйста, смотрите stackoverflow.com/questions/356578/… для расширенной версии этого скрипта с входным диалектом, который обрабатывает встроенные символы запятой и двойных кавычек!

chrisinmtown 10.09.2020 16:51

В этом ответе используется 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)

Ответ с использованием Python уже был предоставлен. stackoverflow.com/a/35123787/5470883

Alexander Baltasar 25.01.2017 12:39

@AlexanderBaltasar, верно, и выглядит полезным, но не использует код Python для взаимодействия с базой данных. См. Комментарий к этому вопросу.

Ben 26.01.2017 05:29

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

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

Крошечный сценарий bash для выполнения простого запроса к дампу CSV, вдохновленный https://stackoverflow.com/a/5395421/2841607.

#!/bin/bash

# $1 = query to execute
# $2 = outfile
# $3 = mysql database name
# $4 = mysql username

if [ -z "$1" ]; then
    echo "Query not given"
    exit 1
fi

if [ -z "$2" ]; then
    echo "Outfile not given"
    exit 1
fi

MYSQL_DB = ""
MYSQL_USER = "root"

if [ ! -z "$3" ]; then
    MYSQL_DB=$3
fi

if [ ! -z "$4" ]; then
    MYSQL_USER=$4
fi

if [ -z "$MYSQL_DB" ]; then
    echo "Database name not given"
    exit 1
fi

if [ -z "$MYSQL_USER" ]; then
    echo "Database user not given"
    exit 1
fi

mysql -u $MYSQL_USER -p -D $MYSQL_DB -B -s -e "$1" | sed "s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" > $2
echo "Written to $2"

Здесь используется заклинание sed, которое игнорирует встроенные символы двойных кавычек. Предложите вместо этого использовать решение perl.

chrisinmtown 25.09.2020 17:52

У меня работает следующий сценарий bash. При желании он также получает схему для запрошенных таблиц.

#!/bin/bash
#
# export mysql data to CSV
#https://stackoverflow.com/questions/356578/how-to-output-mysql-query-results-in-csv-format
#

#ansi colors
#http://www.csc.uvic.ca/~sae/seng265/fall04/tips/s265s047-tips/bash-using-colors.html
blue='\033[0;34m'
red='\033[0;31m'
green='\033[0;32m' # '\e[1;32m' is too bright for white bg.
endColor='\033[0m'

#
# a colored message 
#   params:
#     1: l_color - the color of the message
#     2: l_msg - the message to display
#
color_msg() {
  local l_color = "$1"
  local l_msg = "$2"
  echo -e "${l_color}$l_msg${endColor}"
}


#
# error
#
# show the given error message on stderr and exit
#
#   params:
#     1: l_msg - the error message to display
#
error() {
  local l_msg = "$1"
  # use ansi red for error
  color_msg $red "Error:" 1>&2
  color_msg $red "\t$l_msg" 1>&2
  usage
}

#
# display usage 
#
usage() {
  echo "usage: $0 [-h|--help]" 1>&2
  echo "               -o  | --output      csvdirectory"    1>&2
  echo "               -d  | --database    database"   1>&2
  echo "               -t  | --tables      tables"     1>&2
  echo "               -p  | --password    password"   1>&2
  echo "               -u  | --user        user"       1>&2
  echo "               -hs | --host        host"       1>&2
  echo "               -gs | --get-schema"             1>&2
  echo "" 1>&2
  echo "     output: output csv directory to export mysql data into" 1>&2
  echo "" 1>&2
  echo "         user: mysql user" 1>&2
  echo "     password: mysql password" 1>&2
  echo "" 1>&2
  echo "     database: target database" 1>&2
  echo "       tables: tables to export" 1>&2
  echo "         host: host of target database" 1>&2
  echo "" 1>&2
  echo "  -h|--help: show help" 1>&2
  exit 1
}

#
# show help 
#
help() {
  echo "$0 Help" 1>&2
  echo "========== = " 1>&2
  echo "$0 exports a csv file from a mysql database optionally limiting to a list of tables" 1>&2
  echo "   example: $0 --database=cms --user=scott --password=tiger  --tables=person --output person.csv" 1>&2
  echo "" 1>&2
  usage
}

domysql() {
  mysql --host $host -u$user --password=$password $database
}

getcolumns() {
  local l_table = "$1"
  echo "describe $l_table" | domysql | cut -f1 | grep -v "Field" | grep -v "Warning" | paste -sd "," - 2>/dev/null
}

host = "localhost"
mysqlfiles = "/var/lib/mysql-files/"

# parse command line options
while true; do
  #echo "option $1"
  case "$1" in
    # options without arguments
    -h|--help) usage;;
    -d|--database)     database = "$2" ; shift ;;
    -t|--tables)       tables = "$2" ; shift ;;
    -o|--output)       csvoutput = "$2" ; shift ;;
    -u|--user)         user = "$2" ; shift ;;
    -hs|--host)        host = "$2" ; shift ;;
    -p|--password)     password = "$2" ; shift ;;
    -gs|--get-schema)  option = "getschema";; 
    (--) shift; break;;
    (-*) echo "$0: error - unrecognized option $1" 1>&2; usage;;
    (*) break;;
  esac
  shift
done

# checks
if [ "$csvoutput" == "" ]
then
  error "ouput csv directory not set"
fi
if [ "$database" == "" ]
then
  error "mysql database not set"
fi
if [ "$user" == "" ]
then
  error "mysql user not set"
fi
if [ "$password" == "" ]
then
  error "mysql password not set"
fi

color_msg $blue "exporting tables of database $database"
if [ "$tables" = "" ]
then
tables=$(echo "show tables" | domysql)
fi

case $option in
  getschema) 
   rm $csvoutput$database.schema
   for table in $tables
   do
     color_msg $blue "getting schema for $table"
     echo -n "$table:" >> $csvoutput$database.schema
     getcolumns $table >> $csvoutput$database.schema
   done  
   ;;
  *)
for table in $tables
do
  color_msg $blue "exporting table $table"
  cols=$(grep "$table:" $csvoutput$database.schema | cut -f2 -d:)
  if [  "$cols" = "" ]
  then
    cols=$(getcolumns $table)
  fi
  ssh $host rm $mysqlfiles/$table.csv
cat <<EOF | mysql --host $host -u$user --password=$password $database 
SELECT $cols FROM $table INTO OUTFILE '$mysqlfiles$table.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
EOF
  scp $host:$mysqlfiles/$table.csv $csvoutput$table.csv.raw
  (echo "$cols"; cat $csvoutput$table.csv.raw) > $csvoutput$table.csv
  rm $csvoutput$table.csv.raw
done
  ;;
esac

Если у вас установлен PHP на сервере, вы можете использовать mysql2csv для экспорта (фактически действительного) файла CSV для произвольного запроса mysql. См. мой ответ в MySQL - ВЫБЕРИТЕ * INTO OUTFILE LOCAL? для получения дополнительной информации / контекста.

Я попытался сохранить имена параметров из mysql, поэтому должно быть достаточно предоставить параметры --file и --query:

./mysql2csv --file = "/tmp/result.csv" --query='SELECT 1 as foo, 2 as bar;' --user = "username" --password = "password"

"Установить" mysql2csv через

wget https://gist.githubusercontent.com/paslandau/37bf787eab1b84fc7ae679d1823cf401/raw/29a48bb0a43f6750858e1ddec054d3552f3cbc45/mysql2csv -O mysql2csv -q && (sha256sum mysql2csv | cmp <(echo "b109535b29733bd596ecc8608e008732e617e97906f119c66dd7cf6ab2865a65  mysql2csv") || (echo "ERROR comparing hash, Found:" ;sha256sum mysql2csv) ) && chmod +x mysql2csv

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

Вы можете использовать следующую команду из редактора SQL / Терминала:

«mysql -h (имя хоста / IP>) -u (имя пользователя) -p (пароль) имя базы данных <(query.sql)> outputFILE (.txt / .xls)»

например имя хоста -x.x.x.x

uname - имя пользователя

пароль - пароль

DBName - employeeDB

queryFile - employee.sql

outputFile - outputFile.xls

mysql -hx.x.x.x -uusername -ppassword employeeDB <employee.sql> outputFile.xls

Убедитесь, что вы выполняете команду из каталога, в котором находится SQL-запрос, или укажите полный путь к местоположению sql-запроса в приведенной выше команде.

Что сработало для меня:

SELECT *
FROM students
WHERE foo = 'bar'
LIMIT 0,1200000
INTO OUTFILE './students-1200000.csv'
FIELDS TERMINATED BY ',' ESCAPED BY '"'
ENCLOSED BY '"'
LINES TERMINATED BY '\r\n';

Ни одно из решений в этом потоке не сработало для моего конкретного случая, у меня были довольно данные json внутри одного из столбцов, которые могли бы испортиться в моем выводе csv. Тем, у кого есть подобная проблема, попробуйте вместо этого строки, заканчивающиеся \ r \ n.

Также еще одна проблема для тех, кто пытается открыть csv с помощью Microsoft Excel, имейте в виду, что существует ограничение в 32 767 символов, которое может содержать одна ячейка, выше этого она переполняется на строки ниже. Чтобы определить, какие записи в столбце имеют проблему, используйте запрос ниже. Затем вы можете обрезать эти записи или обрабатывать их по своему усмотрению.

SELECT id,name,CHAR_LENGTH(json_student_description) AS 'character length'
FROM students
WHERE CHAR_LENGTH(json_student_description)>32767;

Следующее производит вывод разделенный табуляцией и действительный CSV. В отличие от большинства других ответов, этот метод правильно обрабатывает экранирование вкладок, запятых, кавычек и новых строк без какого-либо фильтра потока, такого как sed, awk или tr. В примере показано, как передать удаленную таблицу mysql напрямую в локальную базу данных sqlite с помощью потоков. Это работает без разрешения FILE или разрешения SELECT INTO OUTFILE. Я добавил новые строки для удобства чтения.

mysql -B -C --raw -u 'username' --password='password' --host='hostname' 'databasename'
-e 'SELECT
    CONCAT('\''"'\'',REPLACE(`id`,'\''"'\'', '\''""'\''),'\''"'\'') AS '\''id'\'',
    CONCAT('\''"'\'',REPLACE(`value`,'\''"'\'', '\''""'\''),'\''"'\'') AS '\''value'\''
    FROM sampledata'
2>/dev/null | sqlite3 -csv -separator $'\t' mydb.db '.import /dev/stdin mycsvtable'

2>/dev/null нужен для подавления предупреждения о пароле в командной строке.

Если ваши данные содержат NULL, вы можете использовать в запросе функцию IFNULL ().

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

Шаг 1. Просто оберните все столбцы под CONCAT и используйте опцию as CSVFormat, предоставленную MySQL, чтобы получить результаты с разделителями-запятыми. (или используйте любой разделитель, который хотите). Вот пример:

SELECT 
    CONCAT(u.id,
            ',',
            given,
            ',',
            family,
            ',',
            email,
            ',',
            phone,
            ',',
            ua.street_number,
            ',',
            ua.route,
            ',',
            ua.locality,
            ',',
            ua.state,
            ',',
            ua.country,
            ',',
            ua.latitude,
            ',',
            ua.longitude) AS CSVFormat
FROM
    table1 u
        LEFT JOIN
    table2 ua ON u.address_id = ua.id
WHERE
    role_policy = 31 and is_active = 1;

Шаг 2. Скопируйте результаты из вашего терминала в файл и очистите все символы вертикальной черты (которые формируют макет ваших результатов) с помощью любого текстового редактора.

Шаг 3. Сохраните как файл .csv и все.

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

MAbraham1 07.02.2020 04:49

Если вы получаете сообщение об ошибке secure-file-priv, то также после изменения местоположения целевого файла внутри C:\ProgramData\MySQL\MySQL Server 8.0\Uploads, а также после этого запроса -

SELECT * FROM attendance INTO OUTFILE 'C:\ProgramData\MySQL\MySQL Server 8.0\Uploads\FileName.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

не работает, вам нужно просто заменить \ (backsplash) с запроса на / (forwardsplash)

И это работает !!

Пример:

SELECT * FROM attendance INTO OUTFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/FileName.csv' FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n';

Каждый раз, когда вы запускаете успешный запрос, он каждый раз будет генерировать новый файл csv! Круто, правда?

Это решение помещает SQL-запрос в heredoc и направляет вывод через фильтр:

$cat query.sh 
#!/bin/bash

mysql --defaults-group-suffix=[DATABASE_NAME] --batch << EOF | python query.py
SELECT [FIELDS]
FROM [TABLE]
EOF

Эта версия фильтра python работает без использования модуля csv:

$cat query.py 
import sys

for line in sys.stdin:
    print(','.join(["\"" + str(element) + "\"" for element in line.rstrip('\n').split('\t')]))

Эта версия фильтра python использует модуль csv и включает немного больше кода, но, возможно, немного более понятна:

$cat query.py 
import csv, sys

csv_reader = csv.reader(sys.stdin, delimiter='\t')
csv_writer = csv.writer(sys.stdout, quoting=csv.QUOTE_NONNUMERIC)

for line in csv_reader:
    csv_writer.writerow(line)

Или вы можете использовать панды:

$cat query.py 
import csv, sys
import pandas as pd

df = pd.read_csv(sys.stdin, sep='\t')
df.to_csv(sys.stdout, index=False, quoting=csv.QUOTE_NONNUMERIC)

Я столкнулся с той же проблемой, и Ответ Павла не подходил, так как это был RDS. Замена вкладки запятыми не сработала, поскольку в данные были встроены запятые и вкладки. Я обнаружил, что микли, который является альтернативой для mysql-client, поддерживает вывод csv из коробки с флагом --csv

mycli db_name --csv -e "select * from flowers" > flowers.csv

Работает как шарм, вы можете установить mycli в macOS через: brew update && brew install mycli. Я больше никогда не использую стандартный клиент mysql, mycli настолько легален!

bithavoc 24.07.2020 05:40

Mycli и его кузен pgcli фантастические. Я пришел сюда, чтобы добавить этот совет mysql, потому что с другими решениями я ничего не добился. Чистый вывод в локальный .csv с mysql на удивление труден.

iturgeon 04.09.2020 22:17

Здорово, так грустно, что этот ответ получил очень мало лайков. Это единственное решение, которое мне подходит. Все остальное не сработало для меня идеально, кроме этого. У меня были разрывы строк в столбцах - и это привело к появлению новых строк в программе Excel при открытии файла.

Skiff 21.11.2020 02:57

Этот ответ не сработает, если вы застряли при использовании версии 1.8.1 (возможно, потому, что вы используете более старую ОС, в которой все еще есть Python 2.x), поскольку '--csv' не был доступен в этой версии.

Joseph Van Riper 14.12.2020 12:35

Для тех, кто может захотеть скачать результат запроса в формате CSV, но не имеет доступа к файлу сервера, но к базе данных. Во-первых, это не команда linux. Шаги ниже:

  1. Создайте представление с запросом. Например: (Create VIEW v as (Select * from user where status = 0))
  2. Представление будет создано в разделе view вашей базы данных.
  3. Теперь экспортируйте представление как CSV.
  4. Если вам нужен столбец таблицы в качестве заголовка CSV, установите Export method: на Custom - display all possible options и отметьте Put columns names in the first row.

Если вы получаете эту ошибку при попытке экспортировать файл

ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

и вы не можете решить эту ошибку. Вы можете сделать одно, просто запустив этот скрипт Python

import mysql.connector
import csv

con = mysql.connector.connect(
    host = "localhost",
    user = "root",
    passwd = "Your Password"
)

cur = con.cursor()

cur.execute("USE DbName")
cur.execute("""
select col1,col2 from table
where <cond>
""")

with open('Filename.csv',mode='w') as data:
    fieldnames=["Field1","Field2"]
    writer=csv.DictWriter(data,fieldnames=fieldnames)
    writer.writeheader()
    for i in cur:
        writer.writerow({'Field1':i[0],'Field2':i[1]})

Добро пожаловать в Stack Overflow! Это не отвечает на вопрос. Пожалуйста, просмотрите stackoverflow.com/help/how-to-answer.

stephenwade 04.04.2020 19:25

Стоя на плечах @ChrisJohnson, я расширил ответ от февраля 2016 года на собственный диалект для чтения. Этому инструменту конвейера оболочки не нужно подключаться к вашей базе данных, он обрабатывает случайные запятые и кавычки на входе и прекрасно работает в Python2 а также Python3!

#!/usr/bin/env python
import csv
import sys
# fields are separated by tabs; double-quotes may occur anywhere
csv.register_dialect("mysql", delimiter = "\t", quoting=csv.QUOTE_NONE)
tab_in = csv.reader(sys.stdin, dialect = "mysql")
comma_out = csv.writer(sys.stdout, dialect=csv.excel)
for row in tab_in:
    # print("row: {}".format(row))
    comma_out.writerow(row)

Используйте этот оператор печати, чтобы убедиться, что он правильно анализирует ваш ввод :)

Главное предостережение: обработка символов возврата каретки, ^ M aka control-M, \ r в терминах Linux. Альтернативный вывод Mysql в пакетном режиме правильно экранирует встроенные символы новой строки, поэтому действительно есть одна строка на строку (определенная символом новой строки linux \ n), mysql не помещает в кавычки данные столбца. Если элемент данных имеет встроенный символ возврата каретки, csv.reader отклоняет этот ввод с этим исключением:

new-line character seen in unquoted field - 
do you need to open the file in universal-newline mode?

Пожалуйста, не @ мне говорите, что я должен использовать универсальный файловый режим, повторно открыв sys.stdin.fileno с режимом 'rU'. Я пробовал это, это приводит к тому, что встроенные символы \ r обрабатываются как маркеры конца записи, поэтому одна входная запись неправильно преобразовывается во множество неполных выходных записей. Я не нашел решения Python для этого ограничения модуля Python csv.reader. Я думаю, что основной причиной является реализация / ограничение csv.reader, указанное в их документации https://docs.python.org/3/library/csv.html#csv.reader:

The reader is hard-coded to recognise either '\r' or '\n' as end-of-line,
and ignores lineterminator.

Слабое и неудовлетворительное решение, которое я могу предложить, - это изменить каждый символ \ r на двухсимвольную последовательность '\ n' до того, как Python csv.reader увидит данные. Я использовал команду sed. Вот пример конвейера с выбором mysql и скриптом python сверху:

mysql -u user db --execute = "select * from table where id=12345" \
  | sed -e 's/\r/\\n/g' \
  | mysqlTsvToCsv.py

После некоторой борьбы с этим я думаю, что Python - неправильное решение. Если вы можете жить с perl, я думаю, что однострочный сценарий, предлагаемый @artfulrobot, может быть наиболее эффективным и простым решением.

В моем случае from table_name ..... перед INTO OUTFILE ..... выдает ошибку (Unexpected ordering of clauses. (near "FROM" at position 10)).

Что у меня работает.

SELECT *
INTO OUTFILE '/Volumes/Development/sql/sql/enabled_contacts.csv'
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n' 
FROM table_name
WHERE column_name = 'value'

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