【问题标题】:cannot create extension without superuser role没有超级用户角色无法创建扩展
【发布时间】:2013-05-07 19:50:18
【问题描述】:

我正在尝试在 Django 中运行单元测试,它会创建一个新数据库。该数据库具有 postgis 扩展,当我定期创建数据库时,我使用“CREATE ExTENSION postgis”。

但是,当我运行测试时,它给了我以下错误:

$ ./manage.py test
Creating test database for alias 'default'...
Got an error creating the test database: database "test_project" already exists

Type 'yes' if you would like to try deleting the test database 'test_project', or 'no' to cancel: yes
Destroying old test database 'default'...
DatabaseError: permission denied to create extension "postgis"
HINT:  Must be superuser to create this extension.

用户已经拥有 Create DB 权限,我在 Ubuntu 12.04 上使用 PostgreSQL 9.1 和 Postgis 2.0。

【问题讨论】:

    标签: database postgresql postgresql-9.1


    【解决方案1】:

    从 Postgres 13 开始,一些模块/扩展被认为是“受信任的”,并且可以由在当前数据库上拥有 CREATE 权限的非超级用户安装。

    受信任的模块有:btree_gin、btree_gist、citext、cube、dict_int、fuzzystrmatch、hstore、intarray、is、lo、ltree、pgcrypto、pg_trgm、seg、tablefunc、tcn、tsm_system_rows、tsm_system_time、unaccent、uuid-ossp

    要检查给定模块是否符合条件,请访问https://www.postgresql.org/docs/13/contrib.html 并选择有问题的模块。如果它被认为是“受信任的”,则该页面将包含以下句子:

    这个模块被认为是“受信任的”,也就是说,它可以由在当前数据库上拥有CREATE 权限的非超级用户安装。

    【讨论】:

      【解决方案2】:

      在不委派超级用户权限的情况下执行此操作的一种安全方法是使用具有超级用户角色(如 postgres)的用户访问我们正在执行查询的数据库。

      $ sudo -u postgres psql <db_name>
      
      <db_name>#= CREATE EXTENSION IF NOT EXISTS <your-extension>;
      

      这样你就不会暴露安全性并且你可以相信数据库中的扩展。

      GL

      【讨论】:

      • 如果您在 docker 容器中!运行su -u postgrespsql\c &lt;db_name&gt; 并编写CREATE EXTENSION 命令。
      【解决方案3】:

      您也可以将postgis 安装到template1 数据库模板中,该模板默认被所有新创建的数据库继承。

      $ psql -U postgres -d template1 -c "CREATE EXTENSION postgis;"
      

      从此时创建的所有新数据库都将安装 postgis 扩展,包括 Django 的测试数据库,除非它们在创建数据库时指定不同的模板。

      如果不希望在所有新创建的数据库中安装postgis,您可以创建一个新模板,在其中安装postgis,然后让Django 在创建测试数据库时使用此模板。

      $ createdb template_postgis;  # create a new database
      $ psql -U postgres -c "UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template_postgis';"  # make it a template
      $ psql -U postgres -d template_postgis -c "CREATE EXTENSION postgis;"  # install postgis in it
      

      然后在 Django 设置中:

      ...
      DATABASES = {
          'default': {
              ...
              'TEST': {
                  'TEMPLATE': 'template_postgis',
              },
          },
      }
      

      【讨论】:

      • 我对 django-extensions reset_db 有类似的问题。我决定将您的提示与 template1 一起使用(并在其中安装了 postgis)。谢谢你。我只想提一下,在这种情况下,我可以使用以下方法创建没有 postgis 的数据库:CREATE DATABASE dbname TEMPLATE template0;
      • 您确定在数据库字典中使用 TEMPLATE 有效吗?我正在尝试它,而不是它不起作用。另外,我在上面找不到任何文档。
      【解决方案4】:

      django docs 中建议的另一种解决此问题的方法

      $ psql <db name>
      > CREATE EXTENSION postgis;
      

      您可以以超级用户身份登录数据库并创建一次扩展。然后,您的 api 的 db 用户将可以使用该扩展。当django执行CREATE EXTENSION IF NOT EXISTS postgis时postgres不会抛出。

      如果您在迁移双重检查时看到错误,您在正确的数据库中创建了扩展,示例会话

      $ psql
      => \l            - list databases
      => \c <db name>  - connect to django db
      => create extension postgis;
      

      如果您看到表格spatial_ref_sys,则可以验证扩展是否已安装

      => \dt
                         List of relations
       Schema |            Name            | Type  |  Owner
      --------+----------------------------+-------+----------
       public | spatial_ref_sys            | table | postgres
      

      对于测试,我建议针对本地开发数据库运行它们并授予用户超级用户权限,例如 &gt; ALTER ROLE &lt;user_name&gt; SUPERUSER;

      【讨论】:

      • 我不明白,这个问题专门询问如何在没有超级用户权限的情况下执行此操作。所以我们不能“以超级用户身份登录数据库”。
      • @cglacet 有用的信息很有用
      • 我不同意,stackoverflow 应该是有组织的,有用不足以回答。要么这是不可能的并且应该更新问题(标题),或者你的答案(和所有其他人)应该移动到一个单独的问题(具有用户权限和扩展的良好实践)。由于我不知道答案我无法决定,但目前的状态看起来一团糟
      【解决方案5】:

      我发现最简单的方法是:

      su postgres
      psql
      alter role user_name superuser;
      #then create the extension as the user in a different screen
      alter role user_name nosuperuser;
      

      基本上给用户超级用户短期的权力,然后创建扩展。然后撤销超级用户权限。

      您也可以使用\connect user_name 成为该用户并直接从postgres 用户创建扩展。

      【讨论】:

      • 这是有道理的,让用户拥有超级用户权限毫无意义,减少了攻击面。我喜欢!
      • 然而攻击可能在那么短的时间内存在
      【解决方案6】:

      The Django documentation on postgis has some information on setting up user privileges.

      在最坏的情况下,您可以创建一个新的超级用户:

      $ createuser --superuser <user_name>
      

      或更改现有用户的角色:

      postgres# ALTER ROLE <user_name> SUPERUSER;
      

      【讨论】:

      • 您的应用程序不应以超级用户身份运行。我已经为这个问题提供了一个解决方案。
      • @HarryMoreno 我很久以前在一家机构工作时写过这个答案,该机构的数据库与网络应用程序位于同一台服务器上,并且会在营销活动结束时被拆除,并且不会触及其他用户数据。不过,我总体上同意,我从事的所有其他项目都对用户具有适当的权限(但如果您只是在本地进行测试,为什么不使用超级用户:P)
      • 完全可以理解,如果我经验不足,我只是提出了我想要的答案。希望其他人从我们这里受益。
      猜你喜欢
      • 2023-02-14
      • 2012-12-13
      • 2018-04-05
      • 1970-01-01
      • 2015-11-05
      • 2020-04-13
      • 1970-01-01
      • 2021-05-15
      • 1970-01-01
      相关资源
      最近更新 更多