是否有一种简单的方法可以从Linux命令行运行MySQL查询并以CSV格式输出结果?

以下是我现在正在做的:

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

当有很多列需要用引号括起来时,或者如果结果中有需要转义的引号,就会变得混乱。


当前回答

这个答案使用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)

其他回答

从Save MySQL查询结果到一个文本或CSV文件:

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

注意:该语法可能需要重新排序

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

在MySQL的最新版本。

使用此命令,将不会导出列名。

还要注意/var/lib/ MySQL -files/orders.csv将在运行MySQL的服务器上。MySQL进程运行所在的用户必须具有写入所选目录的权限,否则该命令将失败。

如果您想从远程服务器(特别是托管或虚拟机,如Heroku或Amazon RDS)向本地机器写入输出,则此解决方案不适合。

从你的命令行,你可以这样做:

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*

Credits:将表从Amazon RDS导出到CSV文件

我是这么做的:

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。

这很简单,它适用于任何不需要批处理模式或输出文件的东西:

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

from your_table where etc;

解释:

—> Replace (field1, ' ' ', ' ' ' ') 每个结果都用引号括起来——> concat('"', result1, '"') 在每个引用的结果之间使用逗号——> concat_ws(',', quoted1, quoted2,…)

就是这样!

通过'tr'管道(仅限Unix/Cygwin):

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

注意:这既不处理嵌入的逗号,也不处理嵌入的制表符。