【问题标题】:Django throws "[12728] ERROR: CREATE DATABASE cannot run inside a transaction block" when tried to create postgresql databaseDjango 在尝试创建 postgresql 数据库时抛出“[12728] 错误:CREATE DATABASE 无法在事务块内运行”
【发布时间】:2020-02-18 22:56:41
【问题描述】:

我正在使用最新的 Postgresql 在 python 3.6 上运行 django 2.1.4。 问题是,当我尝试从 django 代码创建数据库时,它返回“当前事务被中止,命令被忽略,直到事务块结束”。这是我的代码->

@transaction.atomic
    def mutate(self, info, username, password, email, name, phone, company, country):
        user = get_user_model()(
            first_name=name,
            username=username,
            email=email,
            is_active=False
        )
        user.set_password(password)
        user.save()

        get_country = Country.objects.filter(id=country).first()
        company = Company(name=company, phone=phone, user=user, country=get_country)
        company.save()

        code = secrets.token_hex(16)
        activation = ActivationCode(user=user, code=code)
        activation.save()

        try:
            with connection.cursor() as cursor:
                cursor.execute("CREATE DATABASE company_" + str(company.id))
        except:
            GraphQLError("Something went wrong! Please contact the support center!")
        finally:
            cursor.close()
            db = CompanyDatabase(db_name="company_" + str(company.id), company=company)
            db.save()

        return CreateUser(user=user, company=company)

但它从 django shell 创建数据库 -> shell image

这是 postgres 日志错误 ->

[12728] ERROR: CREATE DATABASE cannot run inside a transaction block

这是生成的终端错误 ->

Traceback (most recent call last):
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\promise\promise.py", line 487, in _resolve_from_executo
r
    executor(resolve, reject)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\promise\promise.py", line 754, in executor
    return resolve(f(*args, **kwargs))
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\graphql\execution\middleware.py", line 75, in make_it_p
romise
    return next(*args, **kwargs)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\contextlib.py", line 52, in inner
    return func(*args, **kwds)
  File "D:\xERP\graphqltest\users\schema.py", line 68, in mutate
    db.save()
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 718, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 748, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 831, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\base.py", line 869, in _do_insert
    using=using, raw=raw)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\manager.py", line 82, in manager_metho
d
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\query.py", line 1136, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\models\sql\compiler.py", line 1289, in execut
e_sql
    cursor.execute(sql, params)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 100, in execute
    return super().execute(sql, params)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 68, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with
_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\Envy\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
graphql.error.located_error.GraphQLLocatedError: current transaction is aborted, commands ignored until end of transaction block

【问题讨论】:

  • 请不要将您的代码作为图片发布。相反,创建一个Minimal, Reproducible Example 并使用适当的降价来格式化您的代码。
  • 我不认为这是我的问题。我刚刚尝试了没有 transaction_atomic 的代码,它工作得很好。如果我添加 transaction_atomic 装饰器,为什么会抛出错误?
  • 我想说阅读this answer,尽管它并没有真正为您的问题提供具体答案。 transaction_atomic 将启动一个事务,语句将在其中执行,而 Postgres 不允许在事务期间执行 CREATE DATABASE 语句。
  • 非常感谢@MihaiChelaru 兄弟的帮助。我终于意识到,您不能在事务块内创建数据库。因为那没有任何意义。 transaction_atomic 在特定数据库上工作,如果发生任何错误,它会回滚。在其中创建另一个数据库永远不会起作用,因为如果发生任何错误,它就无法删除该数据库。还是谢谢。

标签: django python-3.x postgresql


【解决方案1】:

您必须在运行CREATE DATABASE 之前将连接设置为自动提交模式,否则 psycopg2 会将其包装在显式事务中,从而导致观察到的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-31
    • 2020-12-03
    • 2014-12-16
    • 2020-01-17
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多