利用函数视图实现精细化管控:DolphinDB 非标权限管理指南

news2025/1/12 20:04:04

1. 前言

DolphinDB 提供的用户权限管理功能管控的最小粒度是表级别,无法设置小于表粒度的数据访问权限管控,如限制用户仅能访问表中某些行或某些列的数据。为了满足客户更精细的权限管控需求,我们编写了本教程。

2. 概述

函数视图是封装了访问数据库以及相关计算语句的自定义函数,它提供了一种灵活的方式来控制用户访问数据库和表。用户即使不具备读写数据库原始数据的权限,也可通过执行函数视图,间接访问数据库,得到所需的计算结果。本教程主要介绍如何通过函数视图对表的访问权限实现更加精细和个性化的管控。

本教程中会学习到:

  • 如何在 DolphinDB 中用函数视图实现对表的访问权限实现更加精细和个性化的管控。
  • 如何实现授予某些用户或用户组对某个表只能访问某些行的权限:如授予用户 A 只能访问表1近1年的数据。
  • 如何实现授予某些用户或用户组对某个表只能访问某些列的权限:如授予用户 A 只能访问表1前10列的数据。
  • 如何实现授予某些用户或用户组对某个表只能访问某些行和列的权限:如授予用户 A 只能访问表1近1年的前10列的数据。

3. 测试环境准备

第一步:部署测试环境

  • 部署 DolphinDB 单节点:单节点部署教程。
  • 根据部署教程打开节点 web 编程界面,登陆后运行后续步骤测试代码,默认 admin 账户的密码是 123456。

图3-1 DolphinDB web 编程界面

第二步:创建模拟数据库表

创建本教程示例的分区表,模拟数据内容为:

  • 10年10支股票分钟级别指标,指标列为 col1, col2, col3, …, col49, col50。

粘贴下述代码至 web 编程界面,选中需要执行代码点击执行(执行快捷键:Ctrl+E)即可:

//登陆账户
login("admin", "123456")
//创建数据库和分区表
dbName = "dfs://stock"
tbName = "factor"
if(existsDatabase(dbName)){
	dropDatabase(dbName)
}
db = database(dbName, VALUE, 2023.01.01..2023.01.30)
colNames = `SecurityID`date`time`col1`col2`col3`col4`col5`col6`col7`col8`col9`col10`col11`col12`col13`col14`col15`col16`col17`col18`col19`col20`col21`col22`col23`col24`col25`col26`col27`col28`col29`col30`col31`col32`col33`col34`col35`col36`col37`col38`col39`col40`col41`col42`col43`col44`col45`col46`col47`col48`col49`col50
colTypes = [SYMBOL, DATE, SECOND, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE, DOUBLE]
schema = table(1:0, colNames, colTypes)
db.createPartitionedTable(table=schema, tableName=tbName, partitionColumns='date')
//构建模拟数据
n = 1000000
SecurityID = rand(`000001`000002`000003`000004`000005`000006`000007`000008`000009`000010, n)
date = rand(2015.01.01..2024.12.31, n)
time = 09:30:00 + rand(331, n) * 60
factor = rand(10.0, n:50)
factor.rename!(`col1`col2`col3`col4`col5`col6`col7`col8`col9`col10`col11`col12`col13`col14`col15`col16`col17`col18`col19`col20`col21`col22`col23`col24`col25`col26`col27`col28`col29`col30`col31`col32`col33`col34`col35`col36`col37`col38`col39`col40`col41`col42`col43`col44`col45`col46`col47`col48`col49`col50)
t = table(SecurityID, date, time, factor)
//存入分区表
loadTable("dfs://stock", "factor").append!(t)

成功导入模拟数据后可以执行下述代码,查询前10行数据至内存中查看:

data = select top 10 * from loadTable("dfs://stock", "factor")

返回:

图3-2 部分模拟数据

第三步:创建测试用户

  • 创建用户 testUser1, testUser2。
  • 创建用户组 testGroup1,并将用户 testUser1 和 testUser2 加入该用户组。
login("admin", "123456")
createUser("testUser1", "123456",, false)
createUser("testUser2", "123456",, false)
createGroup("testGroup1", `testUser1`testUser2)

4. 设置行级别访问权限

4.1 限制用户仅能访问表中2023年以前的数据

行级别访问控制细则:

  • 限制用户仅能访问表中2023年以前的数据。
  • 限制用户单次访问不能超过1年的数据。
login("admin", "123456")
def getPre2023(startDate, endDate, cols="*", security=NULL) {
	if (endDate >= 2023.01.01) {
		throw("Not granted to read data after 2023")
	}
	if (startDate < temporalAdd(endDate, -1, "y")) {
		throw("Time duration exceeds 1 year. Please change the dates.")
	}
	whereConditions = [<date between startDate:endDate>]
	if (typestr(security) <> VOID) {
		whereConditions.append!(<SecurityID in security>)
	}
	return eval(sql(select=sqlCol(cols), from=loadTable("dfs://stock", "factor"), where=whereConditions))
}
addFunctionView(getPre2023)
grant("testUser1", VIEW_EXEC, "getPre2023")
  • 参数
    • startDateendDate 开始日期,结束日期,间隔不得超过1年。
    • cols 列名,默认所有列。
    • security 证券代码,默认所有证券代码。

  • 用户 testUser1 调用函数视图访问 2022 年指定证券、指定列的数据。
login("testUser1", "123456")
t = getPre2023(2022.01.01, 2022.12.31, `SecurityID`date`time`col1, `000001`000002)
  • 如果用户指定的日期不被允许访问,将会报错。
t = getPre2023(2022.12.01, 2023.01.31)
// output: Not granted to read data after 2023
  • 如果用户指定的起止日期间隔超过1年,将会报错。
t = getPre2023(2020.01.01, 2021.12.31)
// output: Time duration exceeds 1 year. Please change the dates.

4.2 限制用户仅能访问表中最近一年的数据

行级别访问控制细则:

  • 限制用户仅能访问表中最近一年的数据。
login("admin", "123456")
def getRecentYear(startDate=NULL, endDate=NULL, cols="*", security=NULL) {
	start = temporalAdd(date(now()), -1, "y")
	end = date(now())
	if (startDate == NULL) { date0 = start }
	else if (startDate < start) { throw("Not granted to read data before " + start) }
	else { date0 = startDate }
	if (endDate == NULL) { date1 = end }
	else if (endDate > end) { throw("Not granted to read data after " + end) }
	else { date1 = endDate }
	whereConditions = [<date between date0:date1>]
	if (typestr(security) <> VOID) {
		whereConditions.append!(<SecurityID in security>)
	}
	return eval(sql(select=sqlCol(cols), from=loadTable("dfs://stock", "factor"), where=whereConditions))
}
addFunctionView(getRecentYear)
grant("testUser2", VIEW_EXEC, "getRecentYear")
  • 参数
    • startDate 开始日期,默认1年前。
    • endDate 结束日期,默认今天。
    • cols 列名,默认所有列。
    • security 证券代码,默认所有证券代码。

  • 用户 testUser2 调用函数视图访问近1年所有数据。
login("testUser2", "123456")
t = getRecentYear()
  • 用户 testUser2 调用函数视图访问指定日期开始、指定列的数据。
login("testUser2", "123456")
t = getRecentYear(startDate=2023.07.01, cols=`SecurityID`date`time`col2`col3)
  • 如果用户指定的日期不被允许访问,将会报错。
t = getRecentYear(2023.01.01, 2023.12.31)
// output: Not granted to read data before 2023.03.08

5. 设置列级别访问权限

5.1 限制用户仅能访问表中前10列数据

列级别访问控制细则:

  • 限制用户仅能访问表中前10列的数据。
login("admin", "123456")
def getFirst10Col(startDate, endDate, cols=NULL, security=NULL) {
	grantedCols = loadTable("dfs://stock", "factor").schema()['colDefs']['name'][:10]
	notGranted = not(cols in grantedCols)
	if (typestr(cols) == VOID) { col = grantedCols }
	else if (sum(notGranted) > 0) {	throw("Not granted to read columns " + toStdJson(distinct(cols[notGranted]))) }
	else { col = cols }
	if (startDate < temporalAdd(endDate, -1, "y")) {
		throw("Time duration exceeds 1 year. Please change the dates.")
	}	
	whereConditions = [<date between startDate:endDate>]
	if (typestr(security) <> VOID) {
		whereConditions.append!(<SecurityID in security>)
	}
	return eval(sql(select=sqlCol(col), from=loadTable("dfs://stock", "factor"), where=whereConditions))
}
addFunctionView(getFirst10Col)
grant("testUser1", VIEW_EXEC, "getFirst10Col")
  • 参数
    • startDateendDate 开始日期,结束日期,间隔不得超过1年。
    • cols 列名,默认允许访问的所有列。
    • security 证券代码,默认所有证券代码。

  • 用户 testUser1 调用函数视图访问 2023 年指定证券、指定列的数据。
login("testUser1", "123456")
t = getFirst10Col(2023.01.01, 2023.12.31, `SecurityID`date`time`col5`col6`col7, `000008`000009`000010)
  • 如果用户指定的列不被允许访问,将会报错。
t = getFirst10Col(2023.01.01, 2023.12.31, `SecurityID`date`time`col40`col50)
// output: Not granted to read columns ["col50","col40"]

6. 设置行列级别访问权限

6.1 限制用户仅能访问表中2020年以后的几列数据

login("admin", "123456")
def getCond(startDate, endDate, cols=NULL, security=NULL) {
	grantedCols = `SecurityID`date`time`col46`col47`col48`col49`col50
	notGranted = not(cols in grantedCols)
	if (typestr(cols) == VOID) { col = grantedCols }
	else if (sum(notGranted) > 0) {	throw("Not granted to read columns " + toStdJson(distinct(cols[notGranted]))) }
	else { col = cols }
	if (startDate < 2020.01.01) {
		throw("Not granted to read data before 2020")
	}
	if (startDate < temporalAdd(endDate, -1, "y")) {
		throw("Time duration exceeds 1 year. Please change the dates.")
	}
	whereConditions = [<date between startDate:endDate>]
	if (typestr(security) <> VOID) {
		whereConditions.append!(<SecurityID in security>)
	}
	return eval(sql(select=sqlCol(col), from=loadTable("dfs://stock", "factor"), where=whereConditions))
}
addFunctionView(getCond)
grant("testGroup1", VIEW_EXEC, "getCond")
  • 参数
    • startDateendDate 开始日期,结束日期,间隔不得超过1年。
    • cols 列名,默认允许访问的所有列。
    • security 证券代码,默认所有证券代码。

  • 用户组 testGroup1 中的用户调用函数视图访问2021年指定列所有数据。
login("testUser2", "123456")
t = getCond(2021.01.01, 2021.12.31, `SecurityID`date`time`col47`col48`col49)
  • 如果用户指定的列不被允许访问,将会报错。
t = getCond(2021.01.01, 2021.12.31, `SecurityID`date`time`col44`col45`col46`col47)
// output: Not granted to read columns ["col45","col44"]
  • 如果用户指定的日期不被允许访问,将会报错。
t = getCond(2019.01.01, 2019.12.31, `SecurityID`date`time`col47`col48`col49)
// output: Not granted to read data before 2020

7. 函数视图运维介绍

7.1 添加函数视图

管理员定义函数后,使用 addFunctionView 函数添加函数视图。

login("admin", "123456")
def getCount() {
	return select count(*) from loadTable("dfs://stock", "factor")
}
addFunctionView(getCount)

7.2 删除函数视图

管理员使用 dropFunctionView 函数进行函数视图删除。删除函数视图后,所有被赋予该函数视图权限的用户将无法调用该函数视图。

login("admin", "123456")
dropFunctionView("getCount")

7.3 修改函数视图

管理员先删除函数视图,更改函数后,再添加函数视图。如删除前该函数视图已授权给其他用户,修改后需再次授权。

login("admin", "123456")
dropFunctionView("getCount")
go
def getCount() {
	return select count(*) from loadTable("dfs://stock", "factor") where date >= 2023.01.01
}
go
addFunctionView(getCount)

7.4 撤销用户权限

管理员撤销指定用户的函数视图执行权限后,该用户将无法调用该函数视图,但其他拥有该函数视图权限的用户不受影响。

login("admin", "123456")
revoke("testUser1", VIEW_EXEC, "getPre2023")

8. 常见问题解答(FAQ)

8.1 The FunctionView [xxx] already exists, please drop it before adding a new one

执行 addFunctionView 函数添加新的函数视图时报如下错误:

addFunctionView(getCount) => The FunctionView [getCount] already exists, please drop it before adding a new one

造成问题原因:

  • 已经有同名的函数视图,导致本次添加失败后报错终止任务。

解决方案:

  • 办法1:通过 dropFunctionView 函数 删除已定义的同名函数视图
dropFunctionView("getCount")
  • 方法2:通过 try-catch 语句捕获错误日志并打印,避免因为此行代码导致运行终止
try{addFunctionView(getCount)} catch(ex){print(ex)}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1656178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue打包报错:CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

前言&#xff1a; vue项目&#xff0c;打包报错&#xff1a;CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 报错现象&#xff1a; 报错原因&#xff1a; 这个错误是由Node.js在尝试分配内存时因为系统的可用内存不足而发生的。"JavaScript heap…

远动屏柜作用

远动屏柜作用 远动屏柜是电力系统中的重要设备&#xff0c;主要用于实现远方监控和遥控功能&#xff0c;确保电力系统的安全运行。它主要由远动装置、通讯管理机、交换机、调制解调器、GPS对时装置、数字通道防雷器、模拟通道防雷器、插线板、空气开关、屏柜及附件等组成。 远…

英语学习笔记7——Are you a teacher?

Are you a teacher? 你是教师吗&#xff1f; 词汇 Vocabulary name /neɪm/ n. 名字&#xff0c;名声 英文名字构成&#xff1a; 名 字 姓      given name family name  也叫做&#xff1a;first name last name      例&#xff1a;Yanyan Gao 例句&#xff1…

【prometheus】Pushgateway安装和使用

目录 一、Pushgateway概述 1.1 Pushgateway简介 1.2 Pushgateway优点 1.3 pushgateway缺点 二、测试环境 三、安装测试 3.1 pushgateway安装 3.2 prometheus添加pushgateway 3.3 推送指定的数据格式到pushgateway 1.添加单条数据 2.添加复杂数据 3.SDk-prometheus-…

CISCN 2023 初赛

Web unzip 文件上传页面 upload.php页面源码显示了出来 <?php error_reporting(0); highlight_file(__FILE__);$finfo finfo_open(FILEINFO_MIME_TYPE); if (finfo_file($finfo, $_FILES["file"]["tmp_name"]) application/zip){exec(cd /tmp &am…

致力于双碳减排服务——安科瑞推出碳电表

1. 概述 全球首个“碳关税”——欧盟碳边境调节机制于2023年10月启动试运行。自此&#xff0c;首批纳入欧盟碳边境调节机制的6个行业相关产品在出口至欧盟国家时需提供碳排放数据&#xff0c;这会倒逼国内制造业企业加快开展产品碳足迹核查的步伐。以钢铁行业为例&#xff0c;…

进口家装水管十大品牌哪家好,弗锐德为您推荐进口家装水管领先十大品牌

水管作为家装隐蔽工程之一&#xff0c;选对一款优质的水管是至关重要的&#xff0c;毕竟好的水管能够保证家庭后续几十年的用水安全和健康。今天&#xff0c;小编就和大家说说进口家装水管十大品牌哪家好&#xff1f; 目前国内进口家装水管具有知名度和消费者认可的品牌有&…

Linux网络编程(三)IO复用三 epoll系统调用

三、epoll系统调用 epoll是Linux特有的I/O复用函数。它在实现和使用上与select、poll有很大差异。 epoll使用一组函数来完成任务&#xff0c;而不是单个函数epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中&#xff0c;从而无须像select和poll那样每次调用都要…

JS笔试手撕题

数据劫持 Vue2的Object.defineProperty() Vue2的响应式是通过Object.defineProperty()拦截数据&#xff0c;将数据转换成getter/setter的形式&#xff0c;在访问数据的时候调用getter函数&#xff0c;在修改数据的时候调用setter函数。然后利用发布-订阅模式&#xff0c;在数…

计算机专业,求你别再玩了,我都替你们着急

明确学习目标和方向&#xff1a;确定自己希望在计算机领域的哪个方向深入发展&#xff0c;如前端开发、后端开发、数据库管理、人工智能等。根据目标方向&#xff0c;制定详细的学习计划&#xff0c;确保所学知识与未来职业方向相匹配。 【PDF学习资料文末获取】 扎实基础知识…

effective python学习笔记_推导与生成

用推导取代map和filter 序列推导可取代map和filter&#xff0c;优越性有&#xff1a;1可读性强2不需要map的函数 控制推导逻辑的子表达式不要超过2个 即推导的for层数最多建议两层&#xff0c;多了可读性会下降&#xff0c;反而用for循环会清晰 一层for内可连接多个if&…

为什么要使用大模型

随着OpenAI引领的超大模型风潮&#xff0c;大模型的发展日新月异&#xff0c;如同雨后春笋般茁壮成长。在现今的科技舞台上&#xff0c;每周&#xff0c;甚至每一天&#xff0c;我们都能见证到一个全新模型的开源&#xff0c;这些模型的创新性和实用性不断超越前作&#xff0c;…

激光雷达技术:科技之眼,照亮前行

在科技与人文关怀的交响乐章中&#xff0c;一项名为“蝙蝠避障”使用了激光雷达技术原理及应用的创新成果&#xff0c;正悄然改变着视障朋友们的生活方式&#xff0c;为他们的日常出行铺设了一条充满希望的光明之路。今天&#xff0c;让我们一起深入探讨这项技术如何成为盲人出…

关于Java Chassis 3的契约优先(API First)开发

契约优先&#xff08;API First&#xff09;开发是指应用程序开发过程中&#xff0c;将API设计作为第一优先级的任务。契约优先开发随着Web Services概念的发展而不断得到重视&#xff0c;特别是微服务架构出现以后&#xff0c;API设计成为影响功能开放、性能优化等问题的关键因…

企业外贸邮箱有哪些?国内五大外贸邮箱排行榜

外贸公司在进行跨国业务的时候&#xff0c;需要一个稳定安全的企业邮箱。国内的企业外贸邮箱提供商有很多&#xff0c;目前排行在前五的有Zoho Mail企业邮箱、阿里企业邮箱、网易企业邮箱、腾讯企业邮箱、新浪企业邮箱&#xff0c;今天我们就来详细了解下这些邮箱产品。 一、Z…

球形帐篷:低碳环保的未来多功能建筑—轻空间

球形帐篷是一种创新的建筑形式&#xff0c;以其环保、可持续的特点&#xff0c;正在逐渐成为未来多功能建筑的新趋势。通过采用气膜技术和轻量化材料&#xff0c;球形帐篷将为观众带来与众不同的观影、展览等体验&#xff0c;同时彰显了科技创新与环保共生的理念。 创新科技与环…

VTK数据的读写--Vtk学习记录1--《VTK图形图像开发进阶》

读和写操作是VTK可视化管线两端相关的类--Reader和Writer类 Reader:将外部数据读入可视化管线&#xff0c;主要步骤如下 s1:实例化Reader对象 s2:指定所要读取的文件名 s3:调用Update()促使管线执行 对应的Writer: s1:实例化Writer对象 s2输入要写的数据以及指定写入的文…

N个行业看板组态数据可视化大屏,海量模板库不用代码拖拉就行

芯软云设备管理大数据平台。 芯软云设备管理大数据平台&#xff0c;提供MES工艺模板、能源管理模板、智慧水务模板、智慧农业模板、实际产量、设备管理模板、布局模板等。用户可以选择自己喜欢并适合的模板进行场景构建。平台还提供除模板外&#xff0c;共五大类场景资源&…

IP地址证书的详细申请步骤

IP地址证书申请的条件有两个&#xff0c;一个是此IP必须是公网IP&#xff0c;另一个是IP的80和443端口必须允许短暂开放。满足这两个条件才能为其部署SSL证书。 IP地址ssl证书申请网址链接https://www.joyssl.com/certificate/select/ip_certificate.html?nid16 1 访问提供IP…

【PyTorch实战演练】使用CelebA数据集训练DCGAN(深度卷积生成对抗网络)并生成人脸(附完整代码)

文章目录 0. 前言1. CelebA数据集1.1 核心特性与规模1.2 应用与用途1.3 获取方式1.4 数据预处理 2. DCGAN的模型构建2.1 生成器模型2.2 判别器模型 3. DCGAN的模型训练&#xff08;重点&#xff09;3.1 训练参数3.2 模型参数初始化3.3 训练过程 4. 结果展示4.1 loss值变化过程4…