Анализ выходных данных mysqldump для создания CSV-файлов с заголовками имен полей

#mysql #bash #csv #mysqldump #text-parsing

#bash #csv #mysql #синтаксический анализ текста

Вопрос:

Я пытаюсь написать скрипт bash, который, учитывая имя локальной базы данных MySQL, экспортирует данные из всех своих таблиц в CSV-файлы со строкой заголовка, содержащей имена полей. Например, если в базе данных есть таблицы customers , orders и inventory , я хочу создать дамп трех файлов customers.csv , orders.csv и inventory.csv , включая имена полей в заголовках каждого файла.

Поработав с mysqldump, мне удалось создать все нужные мне csv-файлы, но без строки заголовка имени поля. Команда также создает набор файлов .sql, содержащих только структуру таблицы, в командах SQL. После долгих поисков в Google я не могу найти никого, кто смог бы решить эту проблему без «изобретения колеса» и написания собственного скрипта дампа MySQL. mysqldump великолепен, ему просто не хватает этой маленькой функции. И все нужные мне имена полей находятся прямо в этих файлах SQL, нужно просто разобрать их и добавить строку с именами полей к каждому файлу CSV, верно?

Моя проблема: я новичок в написании сценариев оболочки, и я понятия не имею, как это сделать.

Вот команда mysqldump, которую я сейчас использую:

 mysqldump --host=localhost --user=myusername --password=mypassword 
          --tab=/tmp/db/ --verbose mydatabase 
          --fields-enclosed-by=" --fields-terminated-by=,
  

допустим, база данных mydatabase содержит таблицы customers orders и inventory . Эта команда создаст шесть файлов в каталоге / tmp / db: customers.sql , customers.txt , orders.sql , orders.txt inventory.sql , inventory.txt ,,,,,,,,,,,,,. (текстовые файлы — это файлы CSV, позже мой скрипт изменит расширение файла на .csv)

Файлы .sql выглядят следующим образом (используя клиентов в качестве примера):

 -- MySQL dump 10.13  Distrib 5.1.54, for debian-linux-gnu (i686)
--
-- Host: localhost    Database: mydatabase
-- ------------------------------------------------------
-- Server version       5.1.54-1ubuntu4

/* (i removed some generated comments here) */;

--
-- Table structure for table `customers`
--

DROP TABLE IF EXISTS `customers`;
/* (i removed some generated comments here) */;
CREATE TABLE `customers` (
  `customer_id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(256) NOT NULL,
  `last_name` varchar(256) NOT NULL,
  `email` varchar(256) NOT NULL,
  `phone` varchar(20) NOT NULL,
  `notes` longtext NOT NULL,
  PRIMARY KEY (`customer_id`)
) ENGINE=MyISAM AUTO_INCREMENT=1865 DEFAULT CHARSET=latin1;

/* (i removed some generated comments here) */;
-- Dump completed on 2011-05-01 13:03:02
  

и файлы .txt выглядят так, как вы ожидаете от CSV (строки «data», «like», «this»), но без заголовков имен полей.

Как вы можете видеть, нужные мне имена полей находятся прямо в файлах .sql после «СОЗДАТЬ ТАБЛИЦУ …».

Идеальный скрипт, который я пытаюсь написать, должен выполнять следующее:

  1. запустите команду mysqldump, которую я подробно описал выше.
  2. перебирайте все файлы, соответствующие /tmp /db / *.sql, и для каждого:
    1. проанализируйте имена полей и сгенерируйте «строку», «из», «их», «нравится», «это»
    2. в соответствующем файле .txt вставьте строку имен полей перед первой строкой.
  3. переименуйте все файлы .txt в .csv и удалите все файлы .sql.

Какие-нибудь советы? Я буду возиться с этим весь день, пока не разберусь.

Ответ №1:

Я провел простой тест под Windows.

 create database if not exists test;

use test;

create table csv_header(
id int not null auto_increment primary key,
fname varchar(50),
lname varchar(50),
dob date)
engine = myisam;

insert into csv_header (fname,lname,dob) values 
('nick','smith','2000-12-05'),
('john','white','1990-12-05');

set @str = (select concat("select * from (select ", group_concat(concat("'",column_name,"'"))," union
            select * from ", table_name, ") as t into outfile 'd:/",table_name,".txt'
        fields terminated by ',' 
        lines terminated by 'rn'")
            from information_schema.columns
            where table_schema = 'test' and table_name = 'csv_header'
            order by ordinal_position);

-- select @str;

prepare stmt from @str;
execute stmt;
deallocate prepare stmt;
  

И это содержимое моего csv_header.txt:

 id,fname,lname,dob
1,nick,smith,2000-12-05
2,john,white,1990-12-05 
  

Если это то, что вы ищете, то просто создать хранимую процедуру с курсором, которая перебирает все таблицы в схеме и делает то же самое для каждой из них. Дайте мне знать. 🙂

Ответ №2:

Я не смог найти способ сделать это, учитывая, что:

  • мой сервер БД — это удаленный компьютер с
  • нет NFS
  • ни возможности записи в общий ресурс на моем локальном сервере.

Я создал стандартный SQL-дамп и преобразовал grep-файл в формат CSV.

Ответ №3:

 set group_concat_max_len = 5000;

set @qry = (select concat("select ",group_concat(CONCAT('''', column_name, '''' ) ), " UNION SELECT * FROM " ,table_name,  ' INTO OUTFILE ', " '/tmp/test.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'  ESCAPED BY '"' LINES TERMINATED BY '\n' " ) from information_schema.columns where table_schema = database() and table_name = 'spree_users');

prepare stmt from @qry;
execute stmt;
deallocate prepare stmt;