You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用SQLAlchemy Engine无法启用Supabase行级安全(RLS)及创建策略

问题排查与解决方案

核心原因:事务未提交

SQLAlchemy 使用 engine.connect() 创建的连接默认处于手动事务模式,所有 DDL/DML 操作会在上下文结束时自动回滚,除非显式提交。你的代码中创建表成功是因为部分 PostgreSQL 版本中 CREATE TABLE 会自动提交,但 ALTER TABLE 和 CREATE POLICY 属于需要显式提交的操作,因此被回滚了。

具体修复步骤

1. 使用自动提交的事务上下文

将 engine.connect() 替换为 engine.begin(),它会自动管理事务:上下文结束时自动提交所有操作,出错时回滚。

修改后的代码:

def create_table(table_name):
    table_name = table_name.lower()
    # 使用begin()自动管理事务
    with engine.begin() as conn:
        # Create table
        query = text(
            f"""
            CREATE TABLE IF NOT EXISTS {table_name} (
                id UUID PRIMARY KEY,
                user_id UUID references auth.users (id) NOT NULL
            );
            """
        )
        conn.execute(query)
        st.write(f'Table "{table_name}" created in database')

        # Enable RLS
        query = text(
            f"""
            ALTER TABLE {table_name} ENABLE ROW LEVEL SECURITY;
            """
        )
        conn.execute(query)
        st.write(f'RLS for table "{table_name}" created in database')

        # Create Policy(添加IF NOT EXISTS避免重复创建报错)
        query = text(
            f"""
            CREATE POLICY IF NOT EXISTS "User can CRUD their own tables only"
            ON public.{table_name}
            FOR ALL
            TO authenticated
            USING (
                auth.uid() = user_id
            )
            WITH CHECK (
                auth.uid() = user_id
            );
            """
        )
        conn.execute(query)
        st.write(f'Policy for table "{table_name}" created in database')

2. (备选)手动提交事务

如果坚持使用 engine.connect(),需要在所有操作后显式调用 conn.commit():

with engine.connect() as conn:
    # ... 执行所有SQL操作 ...
    conn.commit()  # 显式提交事务

3. 添加异常捕获排查错误

为了确认操作是否真的执行成功,添加异常捕获打印错误信息:

def create_table(table_name):
    table_name = table_name.lower()
    try:
        with engine.begin() as conn:
            # ... 所有SQL操作 ...
    except Exception as e:
        st.error(f"操作失败: {str(e)}")
        raise

4. 验证策略与RLS状态

执行完成后,在Supabase SQL编辑器中运行以下命令验证:

-- 检查RLS是否启用
SELECT relname, rowsecurity FROM pg_class WHERE relname = 'your_table_name';

-- 检查策略是否存在
SELECT polname FROM pg_policy WHERE polrelid = 'public.your_table_name'::regclass;

内容的提问来源于stack exchange,提问作者hud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:13:33