Je souhaite tester les requêtes Hive.
Avec mysql, vous pouvez tester docker-compose relativement facilement, mais je veux tester les requêtes Hive de la même manière, mais que dois-je faire? (Cela semble un peu pénible de devenir fou avec docker ..)
C'est pourquoi j'ai choisi un plug-in qui avait l'air bien et l'ai essayé.
J'ai choisi la git star parmi les quelques outils officiellement introduits. Il y avait beaucoup de HiveRunner. (La version est 4.1.0
)
HiveRunner
teste essentiellement la requête comme un test de Junit
.
Il n'a pas besoin de dépendances externes, cela ressemble à une image de HiveServer
sur JVM
et de Junit
exécutant hive sql
sur ce HiveServer
.
Cette fois, nous allons créer un projet avec maven
.
Ce qui suit est le pom
lors de l'exécution cette fois. Il n'y a pas de raison particulière, mais j'ai spécifié l'émulateur BEELINE
.
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.21.0</version>
<configuration>
<forkMode>always</forkMode>
<systemProperties>
<!-- Defaults to HIVE_CLI, other options include BEELINE and HIVE_CLI_PRE_V200 -->
<commandShellEmulator>BEELINE</commandShellEmulator>
</systemProperties>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.klarna</groupId>
<artifactId>hiverunner</artifactId>
<version>4.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
@RunWith(StandaloneHiveRunner.class)
public class TestHiveRunner {
@HiveSQL(files = {})
private HiveShell shell;
/*
*Créer une base de données et une table
*/
@Before
public void setupSourceDatabase() {
shell.execute(
"CREATE DATABASE source_db; " +
"CREATE TABLE source_db.test_table (year STRING, value INT);");
shell.execute(
"CREATE DATABASE my_schema; " +
"CREATE EXTERNAL TABLE my_schema.result " +
"(year STRING, value INT) " +
"STORED AS PARQUET " +
"TBLPROPERTIES (\"parquet.compress\"=\"snappy\")");
}
@Test
public void testMaxValueByYear() {
/*
*Stocker les données de test dans le tableau à agréger
*/
shell.insertInto("source_db", "test_table")
.withColumns("year", "value")
.addRow("2014", 3)
.addRow("2014", 4)
.addRow("2015", 2)
.addRow("2015", 5)
.commit();
/*
*Exécuter une requête agrégée(INSÉRER la requête)
*/
shell.executeStatement("INSERT INTO my_schema.result " +
"SELECT " +
" year, " +
" MAX(value) " +
"FROM " +
" source_db.test_table " +
"GROUP BY year");
/*
*Récupère le résultat de la table où le résultat agrégé est INSERT
*/
List<Object[]> result = shell.executeStatement("SELECT * FROM my_schema.result");
assertEquals(2, result.size());
assertArrayEquals(new Object[]{"2014",4}, result.get(0));
assertArrayEquals(new Object[]{"2015",5}, result.get(1));
}
}
Il s'agit d'une version légèrement réécrite du code dans la plupart des exemples ci-dessus.
Il semble que ce soit très facile à tester.
Il est également possible de lire la requête extraite, ou lorsque le nombre d'insertions de données de test augmente et que les données de test sont découpées séparément en tsv
, etc.
@HiveSQL
//Src par défaut/test/Vous faites référence au répertoire des ressources.
@HiveSQL(files = {"create_test_table.sql", "create_max.sql"})
private HiveShell shell;
En spécifiant un fichier SQL dans files = {}
, il sera exécuté automatiquement après la création de l'instance.
En définissant @HiveSQL (files = {...}, autoStart = false)
, il peut être démarré après ** une configuration arbitraire **. (Appelez la méthode start ())
À propos, les éléments qui peuvent être définis dans ** Configuration arbitraire ** sont les suivants. (Il existe de nombreuses méthodes surchargées.)
//Définir HiveConf
void setProperty(String key, String value);
void setHiveConfValue(String key, String value);
//Copier les données de test vers HDFS
void addResource(String targetFile, File sourceFile);
//Enregistrement du script à exécuter au démarrage de HiveShell
// @La même chose est vraie pour HiveSetupScript, mais ce qui suit est un ordre garanti d'exécution du script.
void addSetupScript(String script);
void addSetupScripts(Charset charset, File... scripts);
//Il semble qu'il ouvrira le flux et écrira les données de test sur HDFS
OutputStream getResourceOutputStream(String targetFile);
execute
//Écriture directe
shell.execute("CREATE DATABASE source_db; " +
"CREATE TABLE source_db.test_table (year STRING, value INT);");
//Il est également possible de lire le SQL découpé
shell.execute(Paths.get("src/test/resources/calculate_max.sql"));
Exécutez un script (requête) sans valeur de retour.
Plusieurs requêtes peuvent être exécutées en les séparant par ;
.
Cela signifie-t-il qu'il n'y a pas de valeur de retour car vous pouvez exécuter plusieurs requêtes?
executeQuery & executeStatement
//Vous pouvez également l'exécuter avec executeQuery ci-dessous.
shell.executeStatement("INSERT INTO my_schema.result " +
"SELECT " +
" year, " +
" MAX(value) " +
"FROM " +
" source_db.test_table " +
"GROUP BY year");
//Seul executeQuery peut lire le SQL découpé
shell.execute(Paths.get("src/test/resources/calculate_max.sql"));
Contrairement à ʻexecute, plusieurs requêtes ne peuvent pas être exécutées à la fois, et une erreur se produira si
; ʻest inclus à la fin de la phrase.
Au lieu de cela, «List
insertInto
shell.insertInto("source_db", "test_table")
.withColumns("year", "value")
.addRow("2014", 3)
.addRow("2014", 4)
.addRow("2015", 2)
.addRow("2015", 5)
.commit();
//Vous pouvez également insérer des données à partir de tsv, etc.
shell.insertInto("source_db", "test_table")
.withColumns("year", "value")
.addRowsFromTsv(new File("src/test/resources/insert_data_of_test_table.tsv"))
.commit();
Cette méthode ne sera pas exécutée sans commit ()
.
La préparation des données de test est gênante, mais il est très pratique de les insérer avec tsv
.
Cela semble utile (même si cela semble un peu lourd) lorsque vous voulez tester une requête ou essayer une petite requête.
Par contre, dans une table avec un grand nombre de colonnes, un test lorsque la quantité de données de test est grande, un test d'une requête très compliquée, etc., cela semble difficile en termes de mémoire et de vitesse d'exécution, mais que se passe-t-il (README)? Il existe des instructions pour y faire face ..)
Cela dit, il est tentant de pouvoir tester sql
pour ruche
simplement en mettant hiverunner
dans pom
.
Recommended Posts