使用 'mysqldump' 以 CSV 格式转储所有表

Posted

技术标签:

【中文标题】使用 \'mysqldump\' 以 CSV 格式转储所有表【英文标题】:Dump all tables in CSV format using 'mysqldump'使用 'mysqldump' 以 CSV 格式转储所有表 【发布时间】:2012-08-15 23:16:09 【问题描述】:

我需要以 CSV 格式转储 mysql 中的所有表。

是否有使用mysqldump 的命令 以 CSV 格式输出每个表格的每一行?

【问题讨论】:

您可以使用mysql.exe 程序执行此操作,尝试 SELECT * FROM table INTO OUTFILE 'file_name'。但是你应该手动指定每个表。 【参考方案1】:

首先,我可以给你一个表的答案:

所有这些INTO OUTFILE--tab=tmpfile(和-T/path/to/directory)答案的问题在于它需要在与 MySQL 服务器相同的服务器上运行 mysqldump ,并拥有这些访问权限。

我的解决方案是简单地使用 mysql (not mysqldump) 和 -B 参数,使用 -e 内联 SELECT 语句,然后使用 sed 按摩 ASCII 输出,并以包含标题字段行的 CSV 结束:

例子:

 mysql -B -u username -p password database -h dbhost -e "SELECT * FROM accounts;" \
 | sed "s/\"/\"\"/g;s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g"

"id","登录名","密码","文件夹","电子邮件" "8","玛丽安娜","xxxxxxxxxx","玛丽安娜","" "3","squaredesign","xxxxxxxxxxxxxxxxx","squaredesign","mkobylecki@squaredesign.com" "4","miedziak","xxxxxxxxxx","miedziak","miedziak@mail.com" "5","萨科","xxxxxxxxx","萨科","" "6","罗技 波兰","xxxxxxxxxxxxxx","LogitransPoland","" "7","阿莫斯","xxxxxxxxxxxxxxxxxxxx","阿莫斯","" "9","安娜贝尔","xxxxxxxxxxxxxxxx","安娜贝尔","" “11”,“品牌之父和 儿子","xxxxxxxxxxxxxxxxx","BrandfathersAndSons","" “12”,“想象一下 组","xxxxxxxxxxxxxxxx","ImagineGroup","" "13","EduSquare.pl","xxxxxxxxxxxxxxxxx","EduSquare.pl","" "101","tmp","xxxxxxxxxxxxxxxxxxxxx","_","WOBC-14.squaredesign.atlassian.net@yoMama.com"

在该单行代码的末尾添加一个> outfile.csv,以获取该表的 CSV 文件。

接下来,获取所有您的表的列表

mysql -u username -ppassword dbname -sN -e "SHOW TABLES;"

从那里开始,只需再执行一步即可创建循环,例如,在 Bash shell 中迭代这些表:

 for tb in $(mysql -u username -ppassword dbname -sN -e "SHOW TABLES;"); do
     echo .....;
 done

do; done 之间插入我在上面第1 部分中编写的长命令,但用$tb 替换您的表名。

【讨论】:

如果查询结果超出您要转储到的计算机上的内存,则会失败。有什么解决办法吗? 这似乎没有考虑到其中包含双引号的 STRING 列类型——它们应该被转义,否则它会被破坏。知道该怎么做吗? @Blossoming_Flower :这是用于转义双引号的更新正则表达式:| sed "s/\"/\"\"/;s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" (Properly escape a double quote in CSV) @Olivier , @Blossoming_Flower: 也许是 | sed "s/\"/\"\"/g;s/'/\'/;s/\t/\",\"/g;s/^/\"/;s/$/\"/;s/\n//g" ,添加 g 选项以使输入中的每个 " 加倍?Ruby CSV 期望这样的约定。 这里是不带引号的 sed:sed "s/'//;s/\t/,/g;s/\n//g"【参考方案2】:

此命令将在 /path/to/directory table_name.sqltable_name.txt 中创建两个文件。

SQL 文件将包含表创建模式,而 txt 文件将包含 mytable 表的记录,其中字段由逗号分隔。

mysqldump -u username -p -t  -T/path/to/directory dbname table_name --fields-terminated-by=','

【讨论】:

记得使用 -T/path 指向 mysql 进程可写的内容。 仅当您从与数据库服务器相同的机器上运行 mysqldump 时才有效 如果您遇到 mysql 的安全文件 priv 问题,请执行 SHOW VARIABLES LIKE "secure_file_priv"; 并在您的 mysqldump 命令中使用您被告知的文件夹作为输出文件夹,如果您无法重新启动 mysql 服务器。 【参考方案3】:

如果您使用 MySQL 或 MariaDB,最简单且高效的方式为单个表转储 CSV 是 -

SELECT customer_id, firstname, surname INTO OUTFILE '/exportdata/customers.txt'
  FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
  LINES TERMINATED BY '\n'
  FROM customers;

现在您可以使用其他技术对多个表重复此命令。在此处查看更多详细信息:

https://mariadb.com/kb/en/the-mariadb-library/select-into-outfile/ https://dev.mysql.com/doc/refman/5.7/en/select-into.html

【讨论】:

这似乎是最合适的答案,因为它既灵活又高效。【参考方案4】:

mysqldump 具有 CSV 格式选项:

--fields-terminated-by=name
                  Fields in the output file are terminated by the given
--lines-terminated-by=name
                  Lines in the output file are terminated by the given

name 应包含以下内容之一:

`--fields-terminated-by`

\t"\""

`--fields-enclosed-by=name`
   Fields in the output file are enclosed by the given

--lines-terminated-by

\r \n \r\n

当然,您应该单独对每个表进行 mysqldump。

我建议您将所有表名收集在一个文本文件中。然后,遍历所有运行 mysqldump 的表。这是一个脚本,可以一次转储和 gzip 10 个表:

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u$MYSQL_USER -p$MYSQL_PASS"
SQLSTMT="SELECT CONCAT(table_schema,'.',table_name)"
SQLSTMT="$SQLSTMT FROM information_schema.tables WHERE table_schema NOT IN "
SQLSTMT="$SQLSTMT ('information_schema','performance_schema','mysql')"
mysql $MYSQL_CONN -ANe"$SQLSTMT" > /tmp/DBTB.txt
COMMIT_COUNT=0
COMMIT_LIMIT=10
TARGET_FOLDER=/path/to/csv/files
for DBTB in `cat /tmp/DBTB.txt`
do
    DB=`echo "$DBTB" | sed 's/\./ /g' | awk 'print $1'`
    TB=`echo "$DBTB" | sed 's/\./ /g' | awk 'print $2'`
    DUMPFILE=$DB-$TB.csv.gz
    mysqldump $MYSQL_CONN -T $TARGET_FOLDER --fields-terminated-by="," --fields-enclosed-by="\"" --lines-terminated-by="\r\n" $DB $TB | gzip > $DUMPFILE
    (( COMMIT_COUNT++ ))
    if [ $COMMIT_COUNT -eq $COMMIT_LIMIT ]
    then
        COMMIT_COUNT=0
        wait
    fi
done
if [ $COMMIT_COUNT -gt 0 ]
then
    wait
fi

【讨论】:

这不是 CSV,而是制表符分隔的。 CSV 需要转义逗号、引号等。 @KenWilliams 谢谢。我在--fields-enclosed-by 中添加了双引号。 这会产生错误。 mysqldump: You must use option --tab with --fields-... 我找不到你说你添加的--tab选项。 Cloud SQL 文档描述了如何创建 mysqldump。 cloud.google.com/sql/docs/mysql/import-export 某些选项也可能与为 bigquery 创建 CSV 转储相关,例如 mysqldump ---hex-blob --default-character-set=utf8【参考方案5】:

这对我很有效:

mysqldump <DBNAME> --fields-terminated-by ',' \
--fields-enclosed-by '"' --fields-escaped-by '\' \
--no-create-info --tab /var/lib/mysql-files/

或者如果你只想转储一个特定的表:

mysqldump <DBNAME> <TABLENAME> --fields-terminated-by ',' \
--fields-enclosed-by '"' --fields-escaped-by '\' \
--no-create-info --tab /var/lib/mysql-files/

我转储到/var/lib/mysql-files/ 以避免此错误:

mysqldump: Got error: 1290: The MySQL server is running with the --secure-file-priv option so it cannot execute this statement when execution 'SELECT INTO OUTFILE'

【讨论】:

【参考方案6】:

看起来其他人也有这个问题,现在there is a simple Python script,用于将 mysqldump 的输出转换为 CSV 文件。

wget https://raw.githubusercontent.com/jamesmishra/mysqldump-to-csv/master/mysqldump_to_csv.py
mysqldump -u username -p --host=rdshostname database table | python mysqldump_to_csv.py > table.csv

【讨论】:

请注意,mysqldump-to-csv 在其简单代码中包含一些错误。所以准备好修复它,或者继续使用更慢但稳定的解决方案......【参考方案7】:

您也可以使用dbForge Studio for MySQL 中的数据导出工具来完成。

它将允许您选择部分或所有表格并将其导出为 CSV 格式。

【讨论】:

以上是关于使用 'mysqldump' 以 CSV 格式转储所有表的主要内容,如果未能解决你的问题,请参考以下文章

从命令行将 mysql 数据库转储到纯文本 (CSV) 备份

在 mysqldump 中指定日期格式

从一个非常大的 MySQL 转储文件中以 csv 格式获取数据

使用 mysqldump 格式化每行插入一个?

是否可以使用 mysqldump 转储和导入视图?

mysqldump 未转储视图