2016-02-17 11 views
15

chciałbym wyodrębnić wszystkie Create Statements w moim 50 MySQL baz danych poprzez SHOW CREATE TABLE db.table lub SHOW CREATE TABLE db1.mytable lub SHOW CREATE TABLE db2.sometable lub SHOW CREATE TABLE db3.mytable1. W ten sposób każda z DBS kilka stołów wewnątrz db1(table,mytable...) db2(table1,sometable) and so onJak wyodrębnić instrukcje tworzenia z różnych tabel baz danych MySQL?

Aby zilustrować DB poprzez przykład zapytania:

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 

Stosując dbs<-dbGetQuery(con ,"SHOW DATABASES") można wyodrębnić wszystkich baz danych 50 w DbConnection w postaci wektora. Chciałbym zapętlić każdy DB w dbs i zastosować SHOW CREATE TABLE do każdego wiersza/db. Przypuszczam, że muszę przeanalizować każdy wiersz/db w dbname= mydbname i dbs<-dbGetQuery(con ,"SHOW CREATE TABLE"). Ale ja po prostu nie mogę dowiedzieć się, jak zrobić pętle

próbowałem:

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

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

    }) 

ale że nie robi wydaje się słuszne. Przypuszczam, że muszę jakoś włączyć do pętli con. Inaczej dostanę: Error in .local(drv, ...) : object 'dbname' not found

Tak próbowałem:

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") }}) 

Przypuszczam, że zbliża się do rozwiązania, ale tęsknię za coś:

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

library(foreach) 

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

Odpowiedz

8

Rozważmy to podejście importowania ramkę danych z każdej bazy danych (pomijając te systemowe, INFORMATION_SCHEMA i MYSQL) oraz odpowiadające im tabele. Następnie uruchom instrukcje SHOW CREATE TABLE. Na koniec połącz oryginalną ramkę danych z bindowaną ramką danych instrukcji create.

Teraz jedynym zastrzeżeniem są tabele powtarzające nazwy w różnych bazach danych. Aby zwrócić różne wartości takich kombinacji, używana jest funkcja .

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) 
+0

To nawet lepiej niż się spodziewałem. Dziękuję Ci bardzo!! – Googme

+0

@ Parfait. Czy mogę zadać ci jedno pytanie dotyczące 'stmtsdf <- do.call (rbind, createstmts)' Moje 'creatstmts'jest dość duże, prawie 2MB i otrzymam' Error in rbind (deparse.level, ...): liczba kolumn argumentów nie pasuje "Czy istnieje ogólne podejście do radzenia sobie z tym? – Googme

+0

Myślę, że w moim DB są też 'Widok'. Przypuszczam, że w jakiś sposób zmienia strukturę danych dla 'rbind' – Googme

-4

pierwsze, można po prostu użyć

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

Lub można przejrzeć funkcje stosowania, wartości szczególnie, sapply. W tym miejscu można wykonać parsowanie na ciąg dbConnection, połączyć i uzyskać wszystkie tabele jako listę lub wektor. Następnie można pętli wewnątrz tych, aby uzyskać instrukcje tworzenia tabeli. Tak, to jest w zasadzie zastosowanie wewnątrz wniosku. Dla dobrego wyjaśnienia dotyczą funkcji, można spojrzeć na http://www.r-bloggers.com/using-apply-sapply-lapply-in-r/

+0

Tak, wydaje się, że trzeba użyć zagnieżdżonej pętli. To dlatego wysłałem pytanie. Ponieważ nie mogę go wdrożyć. Zakładam więc, że pierwsza pętla musi wziąć pod uwagę długość. Dziękuję za sugestię. – Googme

3
mysqldump --no-data 

robi dokładnie to, co prosicie. (Może być pożądane inne parametry, aby uniknąć/dołączyć CREATE DATABASE, itp.)

Jeśli wymagane jest późniejsze wyciągnięcie do R, to pytam, czy jest to zadanie jednorazowe, czy powtarzające się. Jednorazowo sugerowałbym ogólnie, że podejście mysqldump może być prostsze.

Powiązane problemy