是否有一种简单的方法可以从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
当有很多列需要用引号括起来时,或者如果结果中有需要转义的引号,就会变得混乱。
是否有一种简单的方法可以从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
当有很多列需要用引号括起来时,或者如果结果中有需要转义的引号,就会变得混乱。
当前回答
如果在服务器上设置了PHP,可以使用mysql2csv为任意MySQL查询导出一个(实际上有效的)CSV文件。看到我的答案在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 via
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
(下载要点内容,检查校验和,使其可执行)
其他回答
从你的命令行,你可以这样做:
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文件
到目前为止,除了MySQL Workbench之外,所有的解决方案都是不正确的,而且很可能对MySQL数据库中的某些内容不安全(即安全问题)。
MySQL Workbench(以及类似的phpMyAdmin)提供了一个正式的正确解决方案,但它们是为将输出下载到用户的位置而设计的。它们对于自动化数据导出之类的事情不是很有用。
这是不可能产生可靠的正确的CSV内容从mysql -B -e 'SELECT…'因为它不能编码回车符和字段中的空白。mysql的'-s'标志确实做反斜杠转义,并可能导致一个正确的解决方案。但是,使用脚本语言(具有良好的内部数据结构的语言,而不是Bash)和已经仔细解决编码问题的库要安全得多。
我想过为此写一个脚本,但当我想到我该怎么称呼它时,我突然想到要搜索同名的已有作品。虽然我还没有彻底讨论它,但mysql2csv看起来很有前途。不过,根据应用程序的不同,使用YAML方法指定SQL命令可能有吸引力,也可能没有吸引力。我对Ruby的最新版本的要求也不感兴趣,因为我的Ubuntu 12.04 (Precise穿山甲)笔记本电脑或Debian 6.0 (Squeeze)服务器都是标准版本。是的,我知道我可以使用RVM,但是我宁愿不为了这样一个简单的目的而维护RVM。
您可以有一个使用CSV引擎的MySQL表。
然后你的硬盘上就会有一个CSV格式的文件,你可以直接复制而不用处理它。
下面是在user7610基础上实现这一点的最佳方法。使用mysql outfile有60分钟的文件所有权和覆盖问题。
这并不酷,但它在5分钟内就起作用了。
PHP csvdump.php本地主机根密码数据库表名>
<?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);
?>
这个答案使用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)