Як вивести результати запитів MySQL у форматі CSV?


1183

Чи є простий спосіб запустити запит 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

Він стає безладним, коли є багато стовпців, які потрібно оточити лапками, або якщо в результатах є цитати, які потрібно уникнути.


1
Ви можете використовувати REPLACE()у своєму запиті, щоб уникнути цитат.
dsm

Подивіться на мою відповідь в [цій StackOverflow] [1] [1]: stackoverflow.com/questions/12242772 / ...
biniam


2
Прийнята відповідь на це питання про stackoverflow - це, мабуть, найкращий спосіб: stackoverflow.com/questions/3760631/mysql-delimiter-question
Самуель Аслунд

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

Відповіді:


1760

Від 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), це рішення не підходить.


16
@Tomas, якщо у вас є доступ до віддаленої файлової системи та MySQL, ви повинні мати змогу кудись записатись. замість / tmp, спробуйте /home/yourusername/file.csv - якщо це не вдається, і набір результатів не такий великий, ви можете скопіювати вихід із свого SSH-клієнта та вставити на локальну машину.
Майкл Батлер

63
Питання вказало MySQL, а не "відповідність стандартам".
Пол Томблін

35
Як включити заголовок?
Богдан Гусієв

66
@BogdanGusiev, ви можете включити заголовок, попередньо надіславши "SELECT 'order_id', 'product_name', 'qty' UNION" перед реальним запитом. Перший вибір заголовка повертає заголовок, другий запит повертає реальні дані; UNION приєднується до цього разом.
petrkotek

19
@ Майкл Батлер: Ну, ні, власне. Якщо ви використовуєте Amazon RDS, Heroku або будь-яке інше розміщене рішення, ви навряд чи зможете просто написати на чужий сервер.
Кен Кіндер

459
$ mysql your_database --password=foo < my_requests.sql > out.csv

Яка розділена вкладкою. Складіть так, щоб отримати справжній CSV (спасибі @therefromhere):

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

5
не тільки це, але дозволяє створювати контент із віддаленого хоста бази даних, на відміну від іншого запису в локальну файлову систему.
tmarthal

31
Це розділені вкладки, а не розділені комами.
Flimm

13
@Flimm, якщо припустити, що у полях ви не вбудовані коми / вкладки, ви можете їх перетворити, перенісши результат в| sed 's/\t/,/g'
Джон Картер

111
sed 'fix' не компенсує коми, які можуть з’являтися в будь-якій із вибраних даних, і перекривить ваші стовпці, що виводяться відповідно
Joey T

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

204

mysql - партія, -B

Друкуйте результати, використовуючи вкладку як роздільник стовпців, з кожним рядком у новому рядку. За допомогою цього параметра mysql не використовує файл історії. Пакетний режим призводить до нетабличного формату виводу та виділення спеціальних символів. Евакуація може бути відключена за допомогою режиму "необроблений"; див. опис для параметра --raw.

Це дасть вам файл, розділений на вкладці. Оскільки коми (або рядки, що містять кома) не уникаються, змінити роздільник на кому нескладно.


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

5
це найкраще рішення, оскільки на відміну від першого не потрібно мати дозволів на таких серверах, як RDS
Muayyad Alsadi

8
Акуратний трюк: якщо ви збережете файл, розділений на вкладки, як .xls замість .csv, він відкриється в excel без необхідності перетворення "текст у дані" та без проблем регіональних налаштувань.
сербаут

3
@Joey T - вам все одно потрібно уникнути вкладок і повернення перевезення. Також якщо вміст поля виглядає як поле з цитатами або полем, яке імпортується, імпортований вміст може не виглядати як оригінал.
mc0e

2
у вас буде проблема з NULLs .. вони вийдуть як нульові рядки ..
Jonathan

141

Ось досить загальний спосіб зробити це. Знайшов його десь, не можу взяти жодної кредити

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

3
Прапор -e був саме тим, що я шукав! Дякую!
Гаурав Гупта

1
Цей регулярний вираз дійсно дуже простий; як і багато інших відповідей на цій сторінці, це просто очищення результатів з mysql -B. Якщо ви розділили регулярний вираз на окремі висловлювання на окремі рядки, зрозуміти це буде досить просто (для когось, хто знає регулярний вираз).
Май

7
На перший погляд це виглядає досить ламано. Вкладки та повернення перевезення у вмісті будуть неправильно оброблені. "s / '/ \' /;" взагалі нічого не робить, тому що подвійні лапки команди оболонки споживають зворотну косу рису. Багато інших подібних помилок із зворотною косою рисою втрачено. Немає поводження з косою косою рисою в полі db.
mc0e

1
Схоже, ця команда добре працює в Linux, але не в Mac
Hemerson Varela

6
Це порушиться, якщо у вас є текстове поле, яке містить вкладки, звороту косу рису ","та ряд інших речей. Режекс - це не спосіб вирішити цю проблему
підручник

93

Тільки Unix / Cygwin , передайте їх через "tr":

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

NB: Це не обробляє ні вбудовані коми, ні вкладені вкладки.


53

Це врятувало мене кілька разів. Швидко і це працює!

--batch Друк результатів, використовуючи вкладку як роздільник стовпців, з кожним рядком у новому рядку.

- rew вимикає втечу символів (\ n, \ t, \ 0 і \)

Приклад:

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


4
Якщо я щось не пропускаю, це створює файл TSV, а не файл CSV ...
PressingOnAlways

@PressingOnAlways Так. Цитата документа MySQL: "Друкуйте результати, використовуючи вкладку як роздільник стовпців, з кожним рядком у новому рядку." Але розбір не повинен бути проблемою з будь-яким роздільником. Я використовував його для створення файлів excel для свого клієнта.
hrvoj3e

39

Рішення OUTFILE, надане Полом Томбліном, призводить до того, що файл записується на сам сервер MySQL, тому це буде працювати лише в тому випадку, якщо у вас є FILE- доступ, а також доступ до входу або інші засоби для отримання файлу з цього вікна.

Якщо у вас немає такого доступу, а вихід з обмеженими вкладками є розумною заміною CSV (наприклад, якщо ваша кінцева мета - імпорт до Excel), тоді рішення Сербаута (за допомогою mysql --batchта за бажанням --raw) - це шлях.


36

MySQL Workbench може експортувати набори записів до CSV, і, здається, дуже добре обробляє коми в полях. CSV відкривається штрафом OpenOffice.


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

Щойно я виявив, що це може зберегти і XML, що чудово. Я сподіваюся перейти від однієї програми до іншої за допомогою XSLT для перетворення цього XML у файл CSV, придатний для імпорту в цільову програму.
Девід Олівер

mysql workbench - найкращий варіант для функції експорту експорту.
cijagani

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

3
MySQL workbench має незручне витоку пам’яті під час експорту даних у CSV, якщо у вас є великий набір даних, як 1 або 2 мільйони більше рядків, недостатньо 12 ГБ оперативної пам’яті (перевірено на моїй машині Linux), і пам'ять не очищається, якщо ви не вбити або зупинити його. Для великих наборів даних це не є рішенням.
Остіко

33

Як щодо:

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

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

7
Це не вдається для значень поля з пробілами.
Барун-Шарма

29

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

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

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

Я думав над тим, щоб написати сценарій для цього, але, як тільки подумав про те, як би його назвати, мені спало на думку шукати попередньо працю з такою ж назвою. Поки я не ретельно переглянув це, рішення на веб- сайті https://github.com/robmiller/mysql2csv виглядає багатообіцяючим. Залежно від вашої програми, підхід yaml до вказівки команд SQL, можливо, може не звертатись. Я також не в захваті від вимоги до більш нової версії ruby, ніж це стандартно для мого ноутбука Ubuntu 12.04 або Debian Squeeze. Так, я знаю, що я міг би використовувати RVM, але я вважаю за краще не підтримувати це з такою простою метою.

Сподіваємось, хтось вкаже на підходящий інструмент, це трохи перевірило. Інакше я, мабуть, оновлю це, коли знайду або напишу його.


1
Ви маєте рацію, для складних рядків у таблиці ви повинні використовувати якусь гідну бібліотеку, а не просто баш. Я думаю, що nodejs має кращі рішення для подібних дій. як цей приклад
yeya

1
Привіт, хороша відповідь, я б додав посилання на рішення python, запропоноване нижче stackoverflow.com/a/35123787/1504300 , яке працює добре і дуже просто. Я спробував відредагувати вашу публікацію, але
редакцію

26

Багато відповідей на цій сторінці є слабкими, оскільки вони не вирішують загальний випадок того, що може відбутися у форматі 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.

Це можна вдосконалити для обробки дуже великих файлів за допомогою потокового підходу.


8
Ще надійнішим рішенням буде фактично підключитися до бази даних за допомогою Python, тоді вам слід легше робити те, що вам потрібно зробити, щоб боротися з більшими наборами даних (збивання результатів, потокове передавання тощо).
Джош Румбут

@JoshRumbut, дуже пізно, але я змусив stackoverflow.com/a/41840534/2958070 доповнити ваш коментар
Бен


17
  1. логіка:

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

Коли ви створюєте таблицю CSV, сервер створює файл формату таблиці в каталозі бази даних. Файл починається з імені таблиці та має розширення .frm. Двигун зберігання також створює файл даних. Її назва починається з назви таблиці та має розширення .CSV. Файл даних - це звичайний текстовий файл. Під час зберігання даних у таблиці механізм зберігання зберігає їх у файл даних у форматі значень, розділених комами.


1
Приємно, оскільки це правильно без будь-яких інших коригувань.
Ендрю Шульман

13

У цій відповіді використовуються Python та популярна стороння бібліотека PyMySQL . Я додаю це, оскільки бібліотека csv Python є достатньо потужною, щоб правильно обробляти безліч різноманітних смаків, .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
# /programming/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
Олександр Балтасар

4
@AlexanderBaltasar, правильно, і це виглядає корисно, але це не використання коду Python для взаємодії з базою даних. Дивіться коментар до цього питання.
Бен

11

Це просто, і він працює на будь-що, не потребуючи пакетного режиму чи вихідних файлів:

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, ...)

Це воно!


1
Зауважте, що NULLзначення буде пропущено concat_ws(), що призведе до невідповідності стовпців. Щоб цього не сталося, просто замість цього використовуйте порожню рядок: IFNULL(field, '')(або все, що ви використовуєте для представлення NULL)
Marco Roy

10

Як варіант вище, ви можете мати таблицю MySQL, яка використовує двигун CSV.

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


1
Які обмеження цього щодо розміру файлу / пише / читає / тощо?
Зак Сміт

8

Щоб розширити попередні відповіді, наступний однолінійний експорт експортує одну таблицю у вигляді файлів, розділених вкладками. Він підходить для автоматизації, експортування бази даних щодня або близько того.

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    

4
Для переходу до CSV:mysql -B -D mydatabase -e 'select * from mytable' | sed -e 's/\t/,/g'
DSimon

7
Використання sed -e 's/\t/,/g'безпечно лише в тому випадку, якщо ви впевнені, що ваші дані не містять коми або вкладок.
awatts

7

Спираючись на 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);

?>

1
Приємно, чисто і працює швидко - це чудове рішення, якщо ви можете запустити PHP в цьому середовищі!
Джон Фіала

7

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

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


5

Ось що я роблю:

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

5

Не точно як формат CSV, але teeкоманда від клієнта MySQL може використовуватися для збереження виводу у локальний файл:

tee foobar.txt
SELECT foo FROM bar;

Ви можете відключити його за допомогою notee.

Проблема SELECT … INTO OUTFILE …;полягає в тому, що він вимагає дозволу на запис файлів на сервер.


Якщо розширення .csv використовується замість .txt, чи слід знати про форматизацію?
datalifenyc

@myidealab Проблеми з форматуванням виникають із-за коми та ін. CSV - це звичайний текстовий формат, тому проблем із форматуванням не виникає лише після заміни розширення.
jkmartindale

3

Використовуючи рішення, опубліковане Тімом, я створив цей скрипт bash для полегшення процесу (кореневий пароль запитується, але ви можете легко змінити скрипт, щоб попросити будь-якого іншого користувача):

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


3

Якщо на сервері налаштовано PHP, ви можете використовувати mysql2csv для експорту (фактично дійсного) CSV-файла для атрибутивного запиту mysql. Дивіться мою відповідь на MySQL - ВИБІРУЙТЕСЬ * У ВІДХІДНИЙ МІСЦЕ?для трохи більше контексту / інформації.

Я намагався підтримувати імена опцій з, 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

(завантажити вміст суті, перевірити контрольну суму та зробити її виконуваною).


3

Що для мене спрацювало:

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;

2

Якщо ви отримуєте помилку 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)

І це працює !!

Приклад:

ВИБІР * ВІД відвідування ДО OUTFILE 'C: / ProgramData / MySQL / MySQL Server 8.0 / Uploads / FileName.csv' ПОЛИ, ЗАВЕРШЕНІ В ',' ЗАКРИТИ '' 'ЛІНІЇ, ЗАКРІНІ' \ n ';

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


1

Крихітний скрипт 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"

1

Наступний сценарій bash працює для мене. Він необов'язково також отримує схему для запитуваних таблиць.

#!/bin/bash
#
# export mysql data to CSV
#/programming/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

1

Я зіткнувся з тією ж проблемою, і відповідь Павла не була можливою, оскільки це був RDS. Заміна вкладки комами не спрацювала, оскільки в дані були вбудовані коми та вкладки. Я виявив, що mycli, яка є альтернативою для входу для mysql-клієнта, підтримує вихід CSS із поля з --csvпрапором

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

1

Якщо ви отримуєте цю помилку під час спроби експортувати файл

ПОМИЛКА 1290 (HY000): сервер MySQL працює з опцією --secure-file-priv, тому він не може виконати це твердження

і ви не в змозі вирішити цю помилку. Можна зробити одне, просто запустивши цей скрипт 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]})

Ласкаво просимо до переповнення стека! Це не відповідає на запитання. Перегляньте stackoverflow.com/help/how-to-answer .
Stephenwade

0

Якщо на машині, яку ви використовуєте, встановлено 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";
    }
?>

Перевага цього методу полягає в тому, що він не має проблем із варчарними та текстовими полями, у яких є текст, що містить нові рядки. Ці поля правильно цитуються, і ці нові рядки в них будуть інтерпретовані читачем CSV як частина тексту, а не роздільники записів. Це те, що важко виправити після цього з sed або близько того.


1
Це далеко не зайве ускладнення, це єдине рішення, яке йде в напрямку, ймовірно, правильному - хоч і трохи більше роботи. CSV складніший, ніж спочатку, і ви помилилися. наприклад, зворотна косої риски в оригіналі. Краще скористатися бібліотекою, яка опрацювала всі питання для запису до CSV.
mc0e

@ mc0e Зазвичай ви або подвоюєте цитату, або уникаєте цитати. Я вирішив подвоїти цитату, тому мені не потрібен символ втечі. Різне програмне забезпечення має різні уявлення про деталі CSV. Наприклад, LOAD DATA в MySQL дійсно трактує \ як символ втечі, тоді як Open Office Calc цього не робить. Коли я написав відповідь, я експортував дані в електронну таблицю.
user7610

1
Мій код обробляє все, що було потрібно для експорту мого набору даних за той день;) Ваша відповідь також є кроком у правильному напрямку, але, як говорить перший коментар, він повинен 1) підключитися до бази даних sql зі сценарію безпосередньо як а також 2) використовувати належну бібліотеку csv.
користувач7610
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.