Как извлечь операторы создания из разных таблиц баз данных MySQL?

Я хотел бы извлечь все Create Statements в мои 50 MySQL Базы данных через SHOW CREATE TABLE db.table или SHOW CREATE TABLE db1.mytable или SHOW CREATE TABLE db2.sometable или SHOW CREATE TABLE db3.mytable1. Таким образом, каждая из БД имеет несколько таблиц внутри db1(table,mytable...) db2(table1,sometable) and so on

Чтобы проиллюстрировать БД через примерный запрос:

SELECT *
FROM db.table1 m
   LEFT JOIN db1.sometable o ON m.id = o.id
   LEFT JOIN db2.sometables t ON p.id=t.id
   LEFT JOIN db3.sometable s ON s.column='john'


library(RMySQL)
library(DBI)

con <-  dbConnect(RMySQL::MySQL(), 
                    username = "", 
                    password = "",
                    host = "", 
                    port = 3306,
                    dbname= mydbname)#  when using dbs<-dbGetQuery(con ,"SHOW DATABASES") I have to ## dbname= mydbname## to get all DBs 

Используя dbs<-dbGetQuery(con ,"SHOW DATABASES"), я могу извлечь все 50 баз данных в dbConnection в качестве символьного вектора. Я хотел бы перебрать каждый DB в dbs и применить SHOW CREATE TABLE к каждой строке /db. Я полагаю, что я должен разбирать каждую строку /db в dbname= mydbname и dbs<-dbGetQuery(con ,"SHOW CREATE TABLE"). Но я просто не могу понять, как сделать петли

Я пробовал:

apply(dbs, 1, function(row) {
      dbname <- row[]
      for (i in 1:length(dbname)) {

        create<-dbGetQuery(con,"SHOW CREATE TABLE") }

    })

Но это не кажется правильным. Полагаю, я должен каким-то образом включить con в цикл. В противном случае я получу: Error in .local(drv, ...) : object 'dbname' not found

Итак, я попробовал:

apply(dbs, 1, function(row) {
      dbname <- row[]
      for (i in 1:length(dbname)) {
                    con <-  dbConnect(RMySQL::MySQL(), 
                    username = "", 
                    password = "",
                    host = "", 
                    port = 3306,
                    dbname= [i])
        create<-dbGetQuery(con,"SHOW CREATE TABLE") }})

Я полагаю, что это близко к решению, но я что-то пропустил:

dbs<-dbGetQuery(con,"show databases")

library(foreach)

foreach(i = 1:(length(dbs))%dopar%{
  query<-paste("SHOW CREATE TABLE",dbs[i])
  creates<-dbGetQuery(con,query)
})

Ответы

Ответ 1

Рассмотрим этот подход импорта фрейма данных каждой базы данных (без системных, INFORMATION_SCHEMA и MYSQL) и их соответствующих таблиц. Затем запустите операторы SHOW CREATE TABLE. Наконец, слейте исходный фреймворк с привязанным файлом данных созданных операторов.

Теперь одна оговорка - это таблицы, которые повторяют имена между базами данных. Для возврата отдельных значений таких комбинаций используется функция aggregate() by head.

con <-  dbConnect(RMySQL::MySQL(),
                  username = "****", password = "****",
                  host = "****", port = 3306,
                  dbname= "****")
dbtbls <- dbGetQuery(con, "SELECT `TABLE_SCHEMA` AS `Database`, 
                                  `TABLE_NAME` AS `Table`
                            FROM  `INFORMATION_SCHEMA`.`TABLES` 
                            WHERE `TABLE_TYPE` = 'BASE TABLE'
                              AND `TABLE_SCHEMA` NOT LIKE '%SCHEMA%' 
                              AND `TABLE_SCHEMA` NOT LIKE '%MYSQL%' ")
# LIST OF SQL STATEMENTS
sql <- paste0("SHOW CREATE TABLE ", dbtbls$Database, ".", dbtbls$Table)

# LIST OF DATAFRAMES
createstmts <- lapply(sql, function(x) dbGetQuery(con, x))
dbDisconnect(con)

# ROW BIND LIST INTO ONE DATAFRAME TO MERGE WITH ORIGINAL    
stmtsdf <- do.call(rbind, createstmts)
finaldf <- merge(dbtbls, stmtsdf, by='Table')

# RETURN DISTINCT RECORDS
finaldf <- aggregate(.~Database+Table, finaldf, FUN=head, 1)

Ответ 2

mysqldump --no-data

делает именно то, о чем вы просите. (Могут быть другие параметры, которые желательно избегать/включать CREATE DATABASE и т.д.)

Если требование состоит в том, чтобы впоследствии вывести CREATEs в R, тогда я спрашиваю, является ли это одноразовой задачей или повторяющейся задачей. В одно время я бы предположил, что в целом подход mysqldump может быть проще.

Ответ 3

Сначала вы можете просто использовать

for (i in 1:length(dbs)) { } 

Или вы можете изучить применимые функции, в частности, sapply. Там вы можете выполнить синтаксический анализ на строку dbConnection, подключиться и получить все таблицы в виде списка или вектора. Затем вы можете зациклиться на них, чтобы получить инструкции create table. Таким образом, это в основном применяется внутри применять. Для хорошего объяснения применения функций вы можете посмотреть http://www.r-bloggers.com/using-apply-sapply-lapply-in-r/