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

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

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

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

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

Ответы [ 29 ]

5 голосов
/ 29 мая 2014

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

tee foobar.txt
SELECT foo FROM bar;

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

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

3 голосов
/ 16 мая 2018

Если у вас настроен PHP на сервере, вы можете использовать mysql2csv , чтобы экспортировать (действительно действительный) файл CSV для произвольного запроса MySQL. См. мой ответ на MySQL - SELECT * 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

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

3 голосов
/ 16 мая 2013

Используя решение, опубликованное Тимом, я создал этот сценарий 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

1 голос
/ 07 ноября 2018

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

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;
1 голос
/ 14 мая 2018

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

#!/bin/bash
#
# export mysql data to CSV
#/364257/kak-vyvesti-rezultaty-zaprosa-mysql-v-formate-csv
#

#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 голос
/ 01 марта 2018

Крошечный 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 голос
/ 08 сентября 2014

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

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

0 голосов
/ 24 сентября 2018

Вы можете использовать приведенную ниже команду из вашего редактора 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 outputFile.xls

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

0 голосов
/ 17 марта 2012

Если на вашей машине установлен 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 и text, в которых есть текст, содержащий переводы строк. Эти поля правильно заключены в кавычки, и эти новые строки в них будут интерпретироваться читателем CSV как часть текста, а не разделители записей. Это то, что потом трудно исправить с помощью sed или около того.

...