1 min read

R语言实例:检查视图是否可用

背景

在数据仓库中有时会使用视图

视图是一张虚拟表,视图并不另外单独存储和复制数据,它只是一个结构。

视图是基于一些表来实现的,它可以是表中数据记录的子集,也可以是表中某几个字段形成的子集。

如果这些表的定义发生了变化,将不会反映到视图的定义中。此时将根据需要进行手工的同步更新或维护。

由于数据仓库设计地不断迭代,已经业务需求的变化,视图依赖的物理表可能会变更字段名或者减少字段,会导致原定义的视图不再可用,查询会报错。

对数仓中的视图的可用性做检测,以便发现视图定义已经失效的问题并及时纠正更新。

目标

对 Hive 数据仓库中所有的视图查询验证,发现查询报错时,记录对应的视图信息。

R语言实现

获取视图列表

要与 Hive 数据仓库建立连接,基本前提是服务器开放了连接,两边网络要通,驱动也要安装等。

上述条件满足后,该案例通过 odbc 建立连接 ,并使用 dsn 方式指定连接信息,以避免直接暴露服务器地址和账号与秘密。

Hive 元数据中包含了表信息和表类型,可以通过如下表SQL语句获得视图列表。

#### 连接数据库获取数据
con <- dbConnect(drv = odbc::odbc(), dsn = "Hive Driver", encoding = "GBK")


#### 获取视图的查询语句 
sql_init <- "select concat(d.name, '.', t.tbl_name) as full_table_name
from ods.ods_hive_tbls t
left join ods.ods_hive_dbs d on t.db_id = d.db_id
where upper(tbl_type) = 'VIRTUAL_VIEW'
order by full_table_name"

#### 连接数据库获得查询结果
df_init <- dbGetQuery(con, sql_init)

head(sql_init)

生成对应的SQL查询语句

将获得的每个视图,生成对应的查询语句。

library(dplyr)
library(stringr)
library(magrittr)

df_init %<>% # %<>% 符号是在 magrittr 中,先传递给后面,并将最终结果赋值给最开始的对象
  as_tibble() %>%
  mutate(sql = str_c("select * from ", full_table_name, " limit 1"))

初始化写入一个日志文件,先记录执行日期。

cat(file = "virtual_view_error.txt", "-- ",  as.character(Sys.Date()), "\n", append = FALSE)

循环查询及错误处理

这里直接使用 for 循环而不使用向量化运算,只需要顺序执行没段SQL即可,也就是串行执行。


for (i in seq(from = 1, to = nrow(df_init), by = 1)) {
  
  
  print(i)
  
  sql <- df_init$sql[i]

  
  tryCatch({
    
  dbGetQuery(con, sql) # 这里只将sql发送给服务器执行,结果无需保持
    
  }, error = function(e){ # 该案例重点就是记录查询是的报错信息
    
    cat("ERROR :",conditionMessage(e),"\n")
    
    cat(file = "virtual_view_error.txt", sql, "\n", append = TRUE)
    
  }
  )
  
}

查询结束后关闭与服务器的连接。

dbDisconnect(con)

最后查询日志文件 virtual_view_error.txt 即可,如果有某个视图的日志,说明查询报错,也就是视图定义有问题,可能字段、表不存在了或者代码逻辑错误,需要人工去排查。

总结

将R语言与数据库建立连接之后,可以获得数据库表中的信息,并根据业务逻辑建立查询SQL,通过循环查询及对结果的交互反馈实现一些特殊的应用场景,该案例就是检查视图的有效性。