superset详解(七)--报表/看板权限

本文深入解析了Superset中报表和看板的权限管理机制。详细介绍了如何通过datasource_access权限控制用户对特定报表和看板的访问。同时,文章探讨了用户如何基于所有者身份或数据源权限访问与其相关的看板。

这里我们说的访问报表和看板的权限都是对于普通用户来说的。

报表权限

superset的报表是根据datasource_access权限来确定的,也就是说如果你有某个表的权限,那么与这个表相关的报表你都可以访问。

class SliceFilter(SupersetFilter):
    def apply(self, query, func):  # noqa
        if security_manager.all_datasource_access():
            return query

        # TODO(bogdan): add `schema_access` support here
        datasource_perms = self.get_view_menus('datasource_access')
        query = (
            query.outerjoin(SQLTable, self.model.datasource_id == SQLTable.c.id)
            .outerjoin(models.Database, models.Database.id == SQLTable.c.database_id)
            .filter(or_(
                models.Database.perm.in_(datasource_perms),
                self.model.perm.in_(datasource_perms),
            ))
        )
        return query
看板权限

看板是有2方面来限制的,如果你拥有这个看板,你就可以看到这个看板;另一个是根据datasource_access来确定你可以访问的报表,然后有报表找到所关联的看板

class DashboardFilter(SupersetFilter):

    """List dashboards for which users have access to at least one slice or are owners"""

    def apply(self, query, func):  # noqa
        if security_manager.all_datasource_access():
            return query
        Slice = models.Slice  # noqa
        Dash = models.Dashboard  # noqa
        User = security_manager.user_model
        # TODO(bogdan): add `schema_access` support here
        datasource_perms = self.get_view_menus('datasource_access')
        slice_ids_qry = (
            db.session
            .query(Slice.id)
            .outerjoin(SQLTable, Slice.datasource_id == SQLTable.c.id)
            .outerjoin(models.Database, models.Database.id == SQLTable.c.database_id)
            .filter(or_(
                models.Database.perm.in_(datasource_perms),
                Slice.perm.in_(datasource_perms),
            ))
        )
        owner_ids_qry = (
            db.session
            .query(Dash.id)
            .join(Dash.owners)
            .filter(User.id == User.get_user_id())
        )
        query = query.filter(
            or_(Dash.id.in_(
                db.session.query(Dash.id)
                .distinct()
                .join(Dash.slices)
                .filter(Slice.id.in_(slice_ids_qry)),
            ), Dash.id.in_(owner_ids_qry)),
        )
        return query
你遇到了一个常见的 `npm install` 错误: ``` npm error ENOTEMPTY: directory not empty, rename ... -> '/home/gapinyc/superset-prod/superset-5.0.0/superset-frontend/packages/superset-ui-core/node_modules/.d3-scale-qbNTvgZE' ``` 这是 **npm 在重命名目录时失败**,因为目标路径已被占用或系统锁定了文件。这在使用 **lerna/yarn workspace 类型的单体仓库(monorepo)** 项目(如 Superset)中非常常见。 --- ## 🔍 错误原因分析 Superset 使用了 **多包结构(monorepo)**,即: - `/packages/superset-ui-core` - `/packages/superset-ui-connection` - 等等 这些子包有自己的 `node_modules`,而 `npm install` 在根目录运行时会尝试链接依赖、移动文件夹,但在某些情况下: > ❌ `npm` 想把 `d3-scale` 临时重命名为 `.d3-scale-xxx` 来更新它,但原目录非空或被占用 → 报 `ENOTEMPTY` 常见于: - 文件正在被使用(如编辑器打开) - 杀毒软件/WSL 文件系统延迟 - 并发操作冲突 --- ## ✅ 解决方案:彻底清理 + 强制安装 ### ✅ 步骤 1:确保没有进程占用文件 关闭所有可能访问该项目的程序: - VS Code、WebStorm 等编辑器 - 终端标签页(尤其是仍在该目录下的) - Git GUI 工具 然后重新进入目录: ```bash cd ~/superset-prod/superset-5.0.0/superset-frontend ``` --- ### ✅ 步骤 2:强制删除所有 `node_modules`(包括嵌套的) 你之前只删了根目录的 `node_modules`,但没删 `/packages/...` 下的! 执行递归删除: ```bash # 删除根目录和所有 packages 下的 node_modules find . -name "node_modules" -type d -prune -exec rm -rf '{}' + ``` ✅ 这会删除: - `./node_modules` - `./packages/superset-ui-core/node_modules` - `./packages/superset-ui-demo/node_modules` - 所有插件下的 `node_modules` 同时删除锁文件: ```bash rm -f package-lock.json find . -name "package-lock.json" -type f -delete ``` --- ### ✅ 步骤 3:设置淘宝镜像(已做,确认即可) ```bash npm config set registry https://registry.npmmirror.com npm config get registry # 应输出: https://registry.npmmirror.com/ ``` --- ### ✅ 步骤 4:重新运行 `npm install` ```bash npm install ``` ⏳ 耐心等待(可能需要 10~20 分钟),不要中断。 --- ### ✅ 步骤 5:验证是否成功 安装完成后检查: ```bash ls node_modules/cross-env/bin/cross-env.js ``` ✅ 如果存在,则说明依赖安装成功。 再检查子模块是否正常: ```bash ls packages/superset-ui-core/node_modules/d3-scale/package.json ``` 也应该存在。 --- ## 🛠️ 额外建议(避免再次出错) ### 🔧 1. 使用 `npm ci` 替代 `npm install`(推荐用于构建环境) 如果你有完整的 `package-lock.json`,可以用: ```bash npm ci ``` 它比 `npm install` 更严格、更快、更可靠,适合 CI/CD 和生产构建。 > ⚠️ 注意:`npm ci` 要求 `package-lock.json` 存在且与 `package.json` 匹配。 所以先确保锁文件重建: ```bash npm install --package-lock-only # 先生成 lock 文件 npm ci # 再用 ci 安装 ``` --- ### 🔧 2. 推荐改用 `yarn` 构建 Superset(官方更支持) Apache Superset 官方推荐使用 `yarn` 而不是 `npm`,因为它是基于 **Yarn Workspaces** 的 monorepo 结构。 #### ✅ 切换到 yarn 的方法: ```bash # 1. 安装 yarn npm install -g yarn # 2. 回到 superset 根目录(不是 frontend!) cd ~/superset-prod/superset-5.0.0 # 3. 清理 npm 状态 rm -rf node_modules yarn.lock find . -name "node_modules" -type d -prune -exec rm -rf '{}' + # 4. 使用 yarn 安装(自动识别 yarn.lock) yarn install ``` ✅ `yarn` 对 monorepo 支持更好,基本不会出现 `ENOTEMPTY` 问题。 然后进前端目录构建: ```bash cd superset-frontend yarn build ``` 或者直接: ```bash yarn build # 在根目录运行(如果脚本已定义) ``` --- ## ✅ 总结:你现在应该执行的命令序列 ```bash # 1. 回到项目根目录(superset-frontend) cd ~/superset-prod/superset-5.0.0/superset-frontend # 2. 关闭编辑器等占用程序 # 3. 彻底清除所有 node_modules 和 lock 文件 find . -name "node_modules" -type d -prune -exec rm -rf '{}' + rm -f package-lock.json find . -name "package-lock.json" -type f -delete # 4. 设置镜像 npm config set registry https://registry.npmmirror.com # 5. 重新安装 npm install ``` 如果仍然失败 → **强烈建议切换为 `yarn`** ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值