使用nodered操作数据库

缘起

node-red是目前为止我用到的最好的物联网开发工具,它既可以将相关经验沉淀为节点,又可以灵活快速的定制开发,快速的满足用户的奇葩需求。美中不足的是,它是用node写的,在数据处理、库的丰富性上不及Java、Python。
这么好的产品,可惜中文资料太少,2019年下半年我会把node-red手册翻译出来,并写一个系列的文章,请大家监督。
先写数据库这一篇,就是发现node-red的文档,特别是结点模块的文档太少了,这导致一个简单的东西,摸熟需要大半天,有文档一个小时就能搞定。
MySQL、SQLServer、Oracle是最常用到的三种数据库,下面我们就以这三种数据库为例,讲讲怎么用node-red操作数据库。

操作MySQL 与 SQLServer

在node-red仓库中,目前操作MySQL 有三种节点, node-red-node-mysql、node-red-contrib-sqldbs、node-red-contrib-odbc。前两种用法差不多,但node-red-contrib-sqldbs支持 Mysql、MSsql、Postgresql、SQLLite四种数据库。安装这个节点可以搞定四种数据库,大家应该都会选它吧。

配置节点

  1. 创建一个sqldbs节点
    在左侧的palette中,搜索sql就可以看到相关节点,往右侧一拖,我们就得到了一个sqldbs节点。
    使用nodered操作数据库
  2. 配置sqldbs节点
    双击sqldbs节点进入配置界面,先编辑数据库,创建一个数据库连接,里面填写的内容无非是IP、端口、用户名、密码、数据库名。这里需要注意的是在Dialect一行需要选择数据库类型,Mysql、MSsql、Postgresql、SQLLite 的填写内容并没有区别。
    使用nodered操作数据库
    配置数据库操作类型,这个动作有点多余,从SQL语句可以解析出SQL操作类型,node-red-node-mysql不需要做这个配置。
    使用nodered操作数据库

导入SQL语句

sqldbs节点会从msg.topic这个变量中拿SQL,但是其它节点的输出通常是放在msq.payload中(比如MQTT节点、Inject节点),从Inject 节点到sqldbs节点,中间需要一个转换节点,我用了一个function节点。

使用nodered操作数据库

在Inject 节点中,我注入了一个Json串,该串中包含了我要写入的信息,这也能模拟我从其它节点拿到数据的格式。

{
   "name": "longtt",
   "age": 21,
   "class_name": "401"
}

在function节点中,我把json串的信息组装到了SQL语句中,并替换了msg

var insertOneStudent="INSERT INTO student(name, age, class_name) VALUES ('%s', %d, '%s')";

var newMsg = {
"topic": util.format(insertOneStudent, msg.payload.name, msg.payload.age, msg.payload.class_name)
}
 
return newMsg;

执行

点击注入节点按钮,会触发注入操作,在右侧的调试信息窗口,我们可以看到调试信息。去数据库查询,我们可以看到相关数据记录已经成功创建。

操作Oracle

Oracle 数据库操作有两个难点,一个是安装麻烦,一个是节点文档非常少。

安装Oracle操作节点

在node-red节点仓库中,有两个节点 node-red-contrib-oracledb、node-red-contrib-oracledb-mod, node-red-contrib-oracledb已经过时了,节点安装失败。所以我把精力放到节点 node-red-contrib-oracledb-mod 上,但是也遇到了种种问题。

  1. 无法定位到Oracle Client 库
    配置好OracleDB的连接配置后,OracleDB节点会去建数据库连接,这个过程失败了。

    Oracle-server error connection to 119.3.59.75:1521/orcl: DPI-1047: Cannot locate a 64-bit Oracle Client library: 
    "libclntsh.so: cannot open shared object file: No such file or directory". See 
    https://oracle.github.io/odpi/doc/installation.html#linux for help
    Node-oracledb installation instructions: https://oracle.github.io/node-oracledb/INSTALL.html
    You must have 64-bit Oracle client libraries in LD_LIBRARY_PATH, or configured with ldconfig.
    If you do not have Oracle Database on this computer, then install the Instant Client Basic or Basic Light package 
    from 
    http://www.oracle.com/technetwork/topics/linuxx86-64soft-092277.html

    这和Oracle的律师有很大关系,我用过的数据库工具都需要单独安装从Oracle官网下载的instantclient,node-red也不例外。
    于是我就到Oracle官网下载了一个instantclient(具体版本取决于你的操作系统版本),然后在我的.bashrc中添加了以下几条配置(注意路径是我机器的路径)。重启了一下node-red,之后OracleDB节点连接就成功了。

    export LD_LIBRARY_PATH=/root/instantclient_19_3:$LD_LIBRARY_PATH
    export OCI_LIB_DIR=/root/oracle/instantclient_19_3
    export OCI_INC_DIR=/root/oracle/instantclient_19_3/sdk/include
  2. 配置oracle-db
    必须批评一下,oracle-db与数据库的连接配置中没有区分 sid、service-name两种模式,我的数据库用的是service-name这种模式,sid这种模式我没有试验。
    使用nodered操作数据库

    SQL query、Field mappings 两个配置Tab页面,把我绕得很辛苦,花了一天,很多尝试都失败了,我建议大家不要配置这两页。
    使用nodered操作数据库

导入SQL语句

与sqldbs 不同的是,oracle-db的SQL语句用的是msg.query,并且支持利用占位符从msg.payload中组装数据。我仍然使用Inject节点传入Json串,使用function节点进行数据组合。
使用nodered操作数据库
Inject节点的写法参上,在fuction节点中我导入了query,并替换了payload。

var insertOneStudent="INSERT INTO student(id, name, age, class_name) VALUES (:myid, :myname, :myage, :myclassname)";
var newMsg = {
  "query": insertOneStudent,
  "payload": [msg.payload.id, msg.payload.name, msg.payload.age, msg.payload.class_name]
}

return newMsg;

执行

我写了一个Select查询语句,点击注入节点按钮,会触发注入操作,在右侧的调试信息窗口,我们可以看到查询到的信息。

var SelectOneStudent="select * from student where name =:myname";
var newMsg = {
    "query": SelectOneStudent,
    "payload": [msg.payload.name]
}
return newMsg;

使用nodered操作数据库

the ending

node-red 是一款让我惊艳的工具,后面我会继续深入研究下去,写一些更有深度的文章,需要交流的同学请在下面留言。

相关推荐