2016-09-23 23 views
11

Eskiden çeşitli R komut dosyalarının verilerini almak için kullanılan birden çok SQL sorgusunu kodlamak için epey zaman harcadım. Bu sorunu çözmez veritabanında kendisi VIEW s oluşturmanın neden - Bu da önceki sorgudan sonuç gereklidir bazı sorgular içinScala & Spark: SQL deyimlerinin geri dönüşümü

sqlContent = readSQLFile("file1.sql") 
sqlContent = setSQLVariables(sqlContent, variables) 
results = executeSQL(sqlContent) 

ipucu, yani nasıl çalıştığını olduğunu. Spark 2.0 ile zaten

// create a dataframe using a jdbc connection to the database 
val tableDf = spark.read.jdbc(...) 
var tempTableName = "TEMP_TABLE" + java.util.UUID.randomUUID.toString.replace("-", "").toUpperCase 
var sqlQuery = Source.fromURL(getClass.getResource("/sql/" + sqlFileName)).mkString 
sqlQuery = setSQLVariables(sqlQuery, sqlVariables) 
sqlQuery = sqlQuery.replace("OLD_TABLE_NAME",tempTableName) 
tableDf.createOrReplaceTempView(tempTableName) 
var data = spark.sql(sqlQuery) 

aracılığıyla sadece bunu yapmak için bir yolunu Ama bu benim düşünceme göre çok destek olduğunu. Ayrıca, daha karmaşık sorgular, ör. inquoporate subquery factoring'in şu anda çalışmadığı sorgular. gibi daha sağlam bir yolu var mı yeniden hayata vb .select($""), filter($"") kullanılarak Spark.SQL koduna SQL kodunu

genel amacı, bir önceki SQL sorgusu sonuçlarını temsil eden her (birden org.apache.spark.sql.DataFrame s elde etmektir

hangi JOIN her zaman bir kaç s, WITH s, vs.). nDataFrame s götüren Yani n sorgular.

sağlanan ikisinden daha iyi bir seçenek var mı?

Kurulumu: Hadoop v.2.7.3, 2.0.0 Intelli J IDEA 2016.2, Spark Scala 2.11.8, Testcluster Win7 Workstation'da

+0

Tam o alamadım. Tek bir sql dosyasında birden çok sorgunuz var ve her sorgunun sonunda TempView olarak kaydedilmesini istiyorsunuz? Ya da her bir sorgu ile her bir sorguyu kaydeden birden çok sql dosyası ve bir TempView kaydediliyor mu? Sorunun problemini göremiyorum. –

+0

İkincisi, teşekkürler! Bunu açıklığa kavuşturmak için birkaç infos ekledim. – Boern

+0

Tamam, böylece n sql Files'den n DataFrames istiyorsunuz. Eklediğiniz kodda zaten çözüldü. Çözümünüzde "kibarca" olan şey nedir, neden "daha iyi" bir çözüme ihtiyacınız var? - Cevap ne optimize etmeli? –

cevap

1

Bu sizin gereksinimi özellikle açıktır değil ne, ama seni düşünüyorum sorguları böyle bir şey var diyorsun:

SELECT * FROM people LEFT OUTER JOIN places ON ... 
SELECT * FROM (SELECT * FROM people LEFT OUTER JOIN places ON ...) WHERE age>20 

ve beyan ve

SELECT * FROM people LEFT OUTER JOIN places ON ... 
SELECT * FROM <cachedresult> WHERE age>20 
verimli bu yürütmek isteyeyim

her sql deyimi sonucu depolanacağı içine ilişkili bir tablo adı vardır bu yüzden giriş dosyasını artırmak olacağını ulaşmak.

örn.

PEOPLEPLACES\tSELECT * FROM people LEFT OUTER JOIN places ON ... 
ADULTS=SELECT * FROM PEOPLEPLACES WHERE age>18 

Sonra bu yüzden gerekli tüm tabloları oluşturulmuş sırayla sorguları beyan emin olun

parseSqlFile().foreach({case (name, query) => { 
    val data: DataFrame = execute(query) 
    data.createOrReplaceTempView(name) 
} 

gibi bir döngü içinde yürütmek. Diğer bağımlılıklara göre biraz daha fazla ayrıştırma ve sıralama yapar.

Bir RDMS'de bu tabloları Materialized Views olarak adlandırıyorum. diğer bir görünüm, bir görünüm gibi, ancak daha sonra yeniden kullanılmak üzere önbelleğe alınan bir dönüşüm gibi bir dönüşüm.

İlgili konular