Django 单元测试 - 无法创建 django_migrations 表

Posted

技术标签:

【中文标题】Django 单元测试 - 无法创建 django_migrations 表【英文标题】:Django Unit Tests - Unable to create the django_migrations table 【发布时间】:2018-07-13 07:58:15 【问题描述】:

我正在尝试编写一些单元测试并使用manage.py test 运行它们,但由于某种原因脚本无法创建django_migrations 表。

这是完整的错误:

Creating test database for alias 'default'...
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\backends\utils.py", line 83, in _execute
    return self.cursor.execute(sql)
psycopg2.ProgrammingError: no schema has been selected to create in
LINE 1: CREATE TABLE "django_migrations" ("id" serial NOT NULL PRIMA...
                     ^


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\migrations\recorder.py", line 55, in ensure_schema
    editor.create_model(self.Migration)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\backends\base\schema.py", line 298, in create_model
    self.execute(sql, params or None)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\backends\base\schema.py", line 117, in execute
    cursor.execute(sql, params)
  File "C:\Program Files (x86)\Python36-32\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:\Program Files (x86)\Python36-32\lib\site-packages\django\db\backends\utils.py", line 77, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\backends\utils.py", line 83, in _execute
    return self.cursor.execute(sql)
django.db.utils.ProgrammingError: no schema has been selected to create in
LINE 1: CREATE TABLE "django_migrations" ("id" serial NOT NULL PRIMA...
                     ^


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\commands\test.py", line 26, in run_from_argv
    super().run_from_argv(argv)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\commands\test.py", line 59, in handle
    failures = test_runner.run_tests(test_labels)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\test\runner.py", line 601, in run_tests
    old_config = self.setup_databases()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\test\runner.py", line 548, in setup_databases
    self.parallel, **kwargs
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\test\utils.py", line 176, in setup_databases
    serialize=connection.settings_dict.get('TEST', ).get('SERIALIZE', True),
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\backends\base\creation.py", line 68, in create_test_db
    run_syncdb=True,
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\__init__.py", line 141, in call_command
    return command.execute(*args, **defaults)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\core\management\commands\migrate.py", line 200, in handle
    fake_initial=fake_initial,
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\migrations\executor.py", line 91, in migrate
    self.recorder.ensure_schema()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\django\db\migrations\recorder.py", line 57, in ensure_schema
    raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)
django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table (no schema has been selected to create in
LINE 1: CREATE TABLE "django_migrations" ("id" serial NOT NULL PRIMA...
                     ^
)

我尝试运行这些GRANT 建议here 的语句:

grant usage on schema public to <username>;  
grant create on schema public to <username>;

但我仍然收到相同的消息。有什么想法可以解决这个问题吗?可能是 search_path 问题吗?

更新

~ python manage.py makemigrations users
Migrations for 'users':
  users\migrations\0001_initial.py
    - Create model MyUser

~ python manage.py migrate
Operations to perform:
  Apply all migrations: auth, contenttypes, sessions, users
Running migrations:
  No migrations to apply.

我在执行migrate 之前尝试了makemigrations(呃!),但我仍然遇到与以前相同的错误。迁移甚至被应用了吗?我还应该提到,我的 models.py 只有一个模型/表,它不是由 Django“管理”的。

布勒……布勒……布勒……有人吗?

【问题讨论】:

您在运行测试之前是否运行了 ./manage.py migrate appname?您可以尝试使用干净的数据库吗? 是的,我也尝试了migrate 语句,但它说没有迁移。我尝试了一个新的数据库和同样的东西。 你在迁移./manage.py makemigrations appname之前做过吗 不,我没有。但我只是尝试了一下,我得到了同样的结果。请参阅上面的更新。 【参考方案1】:

我遇到了同样的错误,然后解决了。就我而言,我相信这是因为我将 Django 默认架构设置为 django,在运行 $ python manage.py test 时,测试函数试图将一些表迁移到数据库 test 架构 django,但尚未在那里创建架构 django。所以解决方案是(1)允许 Django 测试函数在 public 架构中搜索,或者(2)run unit test without a test database。

从这个问题的公认答案来看,我想我的情况与问题不同。但我认为两者都是由于 Django 无法在搜索路径中找到模式造成的。因此,我在这里发布了我的解决方案。希望它可以帮助类似的情况。

(django-tally-QTYVOJb0) (python3.6) D:\github\django-tally>python manage.py test
Creating test database for alias 'default'...
Got an error creating the test database: database "test" already exists

Type 'yes' if you would like to try deleting the test database 'test', or 'no' to cancel: yes
Destroying old test database for alias 'default'...
Traceback (most recent call last):
  File "C:\Users\guido\.virtualenvs\django-tally-QTYVOJb0\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql)
psycopg2.errors.InvalidSchemaName: no schema has been selected to create in
LINE 1: CREATE TABLE "django_migrations" ("id" serial NOT NULL PRIMA...

对于解决方案(1): settings.py 中的数据库设置以前是这样的。

if 'RDS_HOSTNAME' in os.environ:
    DATABASES = 
        'default': 
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': os.environ['RDS_DB_NAME'],
            'USER': os.environ['RDS_USERNAME'],
            'PASSWORD': os.environ['RDS_PASSWORD'],
            'HOST': os.environ['RDS_HOSTNAME'],
            'PORT': os.environ['RDS_PORT'],
            'OPTIONS': 
                'options': '-c search_path=django'
            ,
            'TEST': 
                'NAME': 'test', # test database name
            ,
        ,
    

现在看起来像这样。我在搜索路径中添加了 public

if 'RDS_HOSTNAME' in os.environ:
    DATABASES = 
        'default': 
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': os.environ['RDS_DB_NAME'],
            'USER': os.environ['RDS_USERNAME'],
            'PASSWORD': os.environ['RDS_PASSWORD'],
            'HOST': os.environ['RDS_HOSTNAME'],
            'PORT': os.environ['RDS_PORT'],
            'OPTIONS': 
                'options': '-c search_path=django,public'
            ,
            'TEST': 
                'NAME': 'test', # test database name
            ,
        ,
    

【讨论】:

这个对我有用,谢谢!【参考方案2】:

对于同样的错误,我做了一些不同的事情,没有什么不同,但我直接去了 psql 服务器(在我的情况下)。它发生在开发过程中。所以,我没有意识到可能的数据丢失。 选择您的数据库。然后,创建架构。

CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;

我从https://***.com/a/13823560/10860596 得到了答案。因为,我遇到了问题,因为我删除了所有表。

【讨论】:

谢谢.. 我在删除所有表格时遇到了同样的问题【参考方案3】:

我认为回答太晚了,但对我有用的只是简单地按照以下步骤操作:

1) open the pg admin application 
2)open the database you created
3)you will see schemas and then right click on it and create the schemas and named it as public then save.
4)then migrate the table from command line you will see migrations

【讨论】:

【参考方案4】:

我最近遇到了类似的问题,结果发现没有为尝试创建对象的用户/角色定义默认架构。为了解决这个问题,我做了一个或两个(我不记得是哪一个):

添加搜索路径:ALTER ROLE &lt;user_name&gt; SET search_path TO schema1, schema2 使用currentSchema 参数连接到数据库

【讨论】:

【参考方案5】:

这对我有用。

CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
GRANT ALL ON SCHEMA public TO <username>;

【讨论】:

以上是关于Django 单元测试 - 无法创建 django_migrations 表的主要内容,如果未能解决你的问题,请参考以下文章

从 1.8 升级到 2.2.4 后,Django 无法创建用于单元测试的表

无法为 Django 的重置密码流程创建集成测试

Django 中单元测试的覆盖设置无法正常工作

Django 测试冻结在数据库创建

Django 单元测试报错没有创建数据表

每次运行时都没有创建测试数据库的 Django 单元测试