#!/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"
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
5
试试这段代码:
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';
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 ///表示替换第二个's between the first // with what'之间的//
"g"末尾是一个修饰符,意思是"all instance, not just first"
^(在此上下文中)表示行的开头
$(在此上下文中)表示行尾
所以,把它全部一起:
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
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结尾的行 .
SELECT id,name,CHAR_LENGTH(json_student_description) AS 'character length'
FROM students
WHERE CHAR_LENGTH(json_student_description)>32767;
0
Paul Tomblin给出的OUTFILE解决方案导致在MySQL服务器本身上写入文件,因此只有在您具有FILE访问权限以及登录访问权限或其他从该框中检索文件的方法时才会起作用 .
如果你没有't have such access, and tab-delimited output is a reasonable substitute for CSV (e.g., if your end goal is to import to Excel), then Serbaut'的解决方案(使用 mysql --batch 和可选的 --raw )是要走的路 .
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';
这个答案使用Python和流行的第三方库PyMySQL . 我'm adding it because 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
# http://stackoverflow.com/questions/12461484/is-it-secure-to-store-passwords-as-environment-variables-rather-than-as-plain-t
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)
181
$ mysql your_database --password=foo < my_requests.sql > out.csv
29 回答
仅Unix / Cygwin,通过'tr'管道:
N.B . :它既不处理嵌入式逗号,也不处理嵌入式选项卡 .
MySQL Workbench可以将记录集导出为CSV,并且它似乎可以很好地处理字段中的逗号 . CSV在OpenOffice中打开很好 .
这很简单,它适用于任何不需要批处理模式或输出文件的东西:
说明:
替换" with " " in each field --> replace(field1, '" ', '“”')
用引号括起每个结果 - > concat(' 99789 ')
在每个引用的结果之间放置一个逗号 - > concat_ws(',',quoted1,quoted2,...)
而已!
此外,如果您在Bash命令行上执行查询,我相信
tr
命令可用于将默认选项卡替换为任意分隔符 .$ echo "SELECT * FROM Table123" | mysql Database456 | tr "\t" ,
迄今为止,除Mysql工作台之外的所有解决方案都是错误的,并且对于mysql数据库中的至少一些可能内容而言可能是不安全的(即安全问题) .
Mysql Workbench(以及类似的PHPMyAdmin)提供了一个正式的正确解决方案,但设计用于将输出下载到用户的位置 . 它们对于自动化数据导出等问题并不那么有用 .
无法从
mysql -B -e 'SELECT ...'
的输出生成可靠正确的csv,因为它无法对字段中的回车符和空格进行编码 . mysql的'-s'标志确实执行反斜杠转义,并可能导致正确的解决方案 . 但是,使用脚本语言(一个具有良好的内部数据结构,而不是bash),以及编码问题已经仔细制定的库更加安全 .我想为此写一个脚本,但是一旦我想到了我彻底完成了什么,https://github.com/robmiller/mysql2csv的解决方案看起来很有希望 . 根据您的应用程序,指定SQL命令的yaml方法可能会或可能不会吸引人 . 为了这么简单的目的,我宁愿不保持这一点 .
希望有人会指出一个合适的工具,这需要进行一些测试 . 否则,当我找到或写一个时,我可能会更新它 .
用于对CSV转储进行简单查询的微小bash脚本,受https://stackoverflow.com/a/5395421/2841607的启发 .
这是我做的:
perl脚本(从其他地方狙击)在将制表符间隔字段转换为CSV方面做得很好 .
要扩展以前的答案,以下单行将单个表导出为制表符分隔文件 . 它适用于自动化,每天导出数据库 .
方便的是,我们可以使用相同的技术列出MySQL的表,并描述单个表上的字段:
试试这段代码:
有关更多信息:http://dev.mysql.com/doc/refman/5.1/en/select-into.html
这节省了我几次 . 快,它的工作原理!
例:
使用Tim发布的解决方案,我创建了这个bash脚本以方便该过程(请求root密码,但您可以轻松修改脚本以询问任何其他用户):
它将创建一个名为: database.table.csv 的文件
除上述答案外,您还可以拥有一个使用CSV引擎的MySQL表 .
然后,您的硬盘上将有一个文件,该文件将始终采用CSV格式,您可以在不进行处理的情况下进行复制 .
从命令行,您可以执行以下操作:
Credits: Exporting table from Amazon RDS into a csv file
以下bash脚本适合我 . 它还可以选择获取所请求表的模式 .
不完全是CSV格式,但MySQL client 的tee command可用于将输出保存到 local 文件中:
您可以使用
notee
禁用它 .SELECT … INTO OUTFILE …;
的问题是它需要在服务器上写文件的权限 .在user7610的基础上,这是最好的方法 .
mysql outfile
有60分钟的文件所有权和覆盖问题 .它并不酷,但它可以在5分钟内完成 .
php csvdump.php localhost root password database tablename > whatever-you-like.csv
CREATE TABLE () (SELECT data FROM other_table ) ENGINE=CSV ;
这是一种相当粗糙的方式 . 发现它在某个地方,不能拿任何功劳
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 ///表示替换第二个's between the first // with what'之间的//
"g"末尾是一个修饰符,意思是"all instance, not just first"
^(在此上下文中)表示行的开头
$(在此上下文中)表示行尾
所以,把它全部一起:
如果您在服务器上设置了PHP,则可以使用mysql2csv导出(实际上有效的)CSV文件以进行abitrary mysql查询 . 有关更多上下文/信息,请参阅my answer at MySQL - SELECT * INTO OUTFILE LOCAL ? .
我试图维护
mysql
中的选项名称,所以它应该足以提供--file
和--query
选项:"Install" mysql2csv via
(下载要点的内容,检查校验和并使其可执行) .
什么对我有用:
这个线程上没有任何解决方案适用于我的特定情况,我在其中一个列中有很多json数据,这会在我的csv输出中搞砸了 . 对于那些有类似问题的人,请尝试使用以\ r \ n结尾的行 .
对于那些试图用Microsoft Excel打开csv的人来说,另一个问题是,请记住,单个单元格可以容纳32,767个字符的限制,高于它溢出到下面的行 . 要确定列中的哪些记录存在问题,请使用以下查询 . 然后,您可以截断这些记录或按照您的意愿处理它们 .
Paul Tomblin给出的OUTFILE解决方案导致在MySQL服务器本身上写入文件,因此只有在您具有FILE访问权限以及登录访问权限或其他从该框中检索文件的方法时才会起作用 .
如果你没有't have such access, and tab-delimited output is a reasonable substitute for CSV (e.g., if your end goal is to import to Excel), then Serbaut'的解决方案(使用
mysql --batch
和可选的--raw
)是要走的路 .如果您正在使用的计算机上安装了PHP,则可以编写PHP脚本来执行此操作 . 它要求PHP安装已安装MySQL扩展 .
您可以从命令行调用PHP解释器,如下所示:
我包含
--php-ini
开关,因为您可能需要使用自己的PHP配置来启用MySQL扩展 . 在PHP 5.3.0上,默认情况下启用了扩展,因此不再需要使用配置来启用它 .然后你可以像任何普通的PHP脚本一样编写导出脚本:
这种方法的优点是,varchar和text字段没有问题,它们的文本包含换行符 . 这些字段被正确引用,其中的这些新行将由CSV阅读器解释为文本的一部分,而不是记录分隔符 . 这是事后很难纠正的sed左右 .
您可以在SQL位置使用以下命令:
“ mysql -h(hostname/IP>) -u(username) -p(password) databasename <(query.sql) > outputFILE(.txt/.xls) ”
例如hostname -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位置的完整路径 .
这将为您提供一个制表符分隔文件 . 由于逗号(或包含逗号的字符串)未被转义,因此将分隔符更改为逗号并不简单 .
本页面上的许多答案都很薄弱,因为它们无法处理CSV格式的一般情况 . 例如字段中嵌入的逗号和引号以及最终总会出现的其他条件 . 我们需要一个适用于所有有效CSV输入数据的通用解决方案 .
这是Python中一个简单而强大的解决方案:
将文件命名为
tab2csv
,将其放在路径上,赋予它执行权限,然后使用它列出:Python CSV处理功能涵盖了CSV输入格式的极端情况 .
这可以通过流方法来改进以处理非常大的文件 .
来自http://www.tech-recipes.com/rx/1475/save-mysql-query-results-into-a-text-or-csv-file/
使用此命令将不会导出列名称 .
另请注意,
/var/lib/mysql-files/orders.csv
将位于运行MySQL的服务器上 . 运行MySQL进程的用户必须具有写入所选目录的权限,否则命令将失败 .如果要从远程服务器(尤其是托管或虚拟机,如Heroku或Amazon RDS)将输出写入本地计算机,则此解决方案不适用 .
这个答案使用Python和流行的第三方库PyMySQL . 我'm adding it because Python'的csv库足够强大,可以正确处理
.csv
的许多不同风格,没有其他答案使用Python代码与数据库进行交互 .哪个是标签分隔 . 像这样管道以获得真正的CSV(感谢@therefromhere):
怎么样: