2016-02-17 19 views
15

Tüm Create Statements, SHOW CREATE TABLE db.table veya SHOW CREATE TABLE db1.mytable veya SHOW CREATE TABLE db2.sometable veya SHOW CREATE TABLE db3.mytable1 aracılığıyla 50 MySQL Veritabanlarımı ayıklamak istiyorum. Böylece veritabanları her bir örnek, bir sorgu ile DBS göstermek için db1(table,mytable...) db2(table1,sometable) and so onMySQL DB'lerin farklı tablolarından ifadeler nasıl oluşturulur?

içinde bazı tablolar var

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 

I karakter vektörü olarak DbConnection bölgesindeki 50 Veritabanları ayıklamak dbs<-dbGetQuery(con ,"SHOW DATABASES") kullanılması. Her DB'ye dbs'da döngü yapmak ve her satır/db'ye SHOW CREATE TABLE uygulamak istiyorum. Her satırı/db'yi dbname= mydbname ve dbs<-dbGetQuery(con ,"SHOW CREATE TABLE")'a ayrıştırmam gerektiğini varsayalım.

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

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

    }) 

Ama o doesnt doğru görünüyor: Ama sadece döngüler

denedim nasıl anlamaya olamaz. Sanırım con'u bir şekilde döngüye dahil etmeliyim. Aksi halde ben alırsınız: Error in .local(drv, ...) : object 'dbname' not found

yüzden çalıştı:

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

ben bu çözüm yaklaşır herhalde ama bir şey kaçırmak:

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

library(foreach) 

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

cevap

8

içine bakabilirsiniz ve bunlara karşılık gelen tablo (sistem olanları, INFORMATION_SCHEMA ve MYSQL dışarıda bırakarak) her veritabanının bir veri çerçevesi ithal bu yaklaşımı göz önünde bulundurun. Ardından, ifadelerini çalıştırın. Son olarak, orijinal veri çerçevesini, oluşturma ifadelerinin bağlanmış veri çerçevesiyle birleştirin.

Şimdi, bir uyarı, veritabanları arasında adları tekrarlayan tablolar. Bu tür kombinasyonların farklı değerlerini döndürmek için aggregate()head işlevi kullanılır.

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

öneri için teşekkür ederiz. Çok teşekkür ederim!! – Googme

+0

@ Parfait. Stmtsdf <- do.call (rbind, createstmts) ile ilgili bir soru sorabilirim '' creatstmts's oldukça büyük, neredeyse 2MB ve rbind'de hata alacağım (deparse.level, ...): argüman sütunlarının sayısı uyuşmuyor 'Bununla başa çıkmak için genel bir yaklaşım var mı? – Googme

+0

Bence DB'mde bazı 'Görünüm'ler de var. Sanırım bir şekilde "rbind" – Googme

-4

İlk olarak, sadece kullanım sadece edebilirsiniz

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

Veya aşağıdaki işlevleri uygulayabilirsiniz: özellikle, sapply. Orada dbConnection dizesi başına ayrıştırma yapabilir, tüm tabloları bağlayabilir ve liste veya vektör olarak alabilirsiniz. Daha sonra tablo ifadeleri oluşturmak için bunların içine girebilirsiniz. Yani, temelde geçerlidir geçerlidir. uygulamak fonksiyonların iyi bir açıklama için, http://www.r-bloggers.com/using-apply-sapply-lapply-in-r/

+0

Evet, yuvalanmış bir döngü kullanmak zorunda gibi görünüyor. Bu yüzden soruyu yolladım. Çünkü onu uygulayamıyorum. Bu yüzden ilk döngünün uzunluğu hesaba katması gerektiğini düşünüyorum. – Googme

3
mysqldump --no-data 

sen soran tam olarak ne yapar. (CREATE DATABASE, vs.'yi önlemek/dahil etmek için başka parametreler de olabilir)

Gereksinim daha sonra CREATEs'u R'ye çekmekse, bunun tek seferlik bir görev mi yoksa yinelenen bir görev mi olduğunu soruyorum. Bir kereliğine, genel olarak, mysqldump yaklaşımının daha basit olabileceğini öneririm.

İlgili konular