[英]How to use in-memory Derby database for testing with Hive (Scala)
我正在使用带有Scala 2.11的spark-hive 2.3.0并设置单元测试框架。 spark-hive附带了TestHiveContext
和TestHiveSparkSession
,它可以方便地从单元测试中调用Hive,而无需运行Hadoop,Spark或集群,这对于自动化测试非常TestHiveSparkSession
。
Hive需要一个用于其Metastore的数据库,当以这种方式运行时,它使用Derby作为使用javax.jdo.option.ConnectionURL
配置的嵌入式数据库,默认情况下为jdbc:derby:;databaseName=<file-path>;create=true
。 <file-path>
是本地文件系统中的一个位置,是运行Derby的一个选项。
另一种选择是在内存中运行Derby,这通常就像将URL更改为类似jdbc:derby:memory:databaseName;create=true
。 Hoewever,这对于Hive是不可能的,因为配置是在内部HiveUtils
类中进行的,并且不能被覆盖。 我试着在我的星火会话生成器改变它,但后来我改变得到由吹走HiveUtils
当我创建我的TestHiveContext
。
在我的情况下,内存数据库是首选,因为我们的开发人员在Windows上运行(绝对不是我/我们的选择),并且当创建这些文件时,通常会出现文件名中的权限或无效字符等问题(因为Hadoop从未真正打算过在Windows上工作),这些文件经常被遗忘,因为它们无法清理(由于这些问题)。 我们希望测试完全独立,因此它们可以在没有副作用的情况下运行和完成,因此它们可以在多个环境(开发人员,CI,Jenkins,AWS等)中运行。
有趣的是我在TestHive.scala
看到了这个:
{ // set the metastore temporary configuration
val metastoreTempConf = HiveUtils.newTemporaryConfiguration(useInMemoryDerby = false) ++ Map(
因此,有一个使用内存数据库的标志,但这是不可配置的,并且没有代码路径将其设置为true
。
有没有办法配置或写这个,以便TestHive
的Derby可以在内存中? 试图通过hive-site.xml或hdfs-site.xml设置javax.jdo.option.ConnectionURL
的值不起作用,我认为这是因为TestHive
, TestHiveContext
和TestHiveSparkSession
如何初始化,它们有自己的代码路径与非测试路径分开。 它们提供的功能对于测试框架非常有用,但显然没有提供覆盖此值和其他一些设置的方法。
到目前为止,我能看到的最好的选择是覆盖或编写我自己的TestHiveContext
类,该类从该类借用了一堆功能并覆盖了我需要的部分,但这对于我认为可以用简单的方法完成的工作来说是一项相对较大的任务。配置改变。
我终于想出了如何做到这一点,并希望分享答案,以防其他人试图做同样的事情。
我的测试类使用SharedSparkContext
性状,它提供了一个SparkContext
经由变种通过引用sc
。
在SparkContext初始化之后(我使用了scalatest
测试框架中提供的beforeAll
钩子),我创建了一个这样的TestHiveContext
:
hc = new TestHiveContext(sc, false)
然后立即,我可以设置javax.jdo.option.ConnectionURL
并可能设置其他一些Hadoop和Hive配置,如下所示:
sc.hadoopConfiguration.set("javax.jdo.option.ConnectionURL",
"jdbc:derby:memory:db;create=true")
此配置参数由Hive使用,但显然必须添加到Hadoop配置中,该配置用于构建Hive测试上下文。
诀窍是时间,这必须在Hadoop和Hive自己初始化后(使用配置文件和诸如此类)完成,并且最初的框架也被初始化,最后在TestHive框架初始化之后,但在运行任何测试之前。 尝试在这些其他初始化之前设置此参数意味着您的设置将在测试运行之前被覆盖。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.