【发布时间】: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