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

10

我正在尝试编写某些单元测试并使用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语句,这里是建议的链接

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所“管控”的。

Bueller...Bueller...Beuller...有人能帮忙吗?


在运行测试之前,您是否运行了“./manage.py migrate appname”命令?您可以尝试使用干净的数据库吗? - Mazel Tov
是的,我也尝试了migrate语句,但它显示没有迁移。我用一个新的数据库尝试了一下,结果还是一样。 - ravioli
你在迁移之前做了什么 ./manage.py makemigrations appname - Mazel Tov
没有,我没有。但是我刚刚尝试了一下,结果得到了相同的东西。请参见上面的更新。 - ravioli
5个回答

8

对于同样的错误,我采取了不同的做法,好吧,并不是不同,而是直接进入了 psql 服务器(在我的情况下)。这发生在开发过程中。所以,我没有意识到可能会丢失数据。 选择你的数据库。然后,创建模式。

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

我从https://dev59.com/3nA75IYBdhLWcg3wYH7I#13823560得到了答案。由于我删除了所有表格,所以出现了问题。


谢谢。我也遇到了删除所有表的同样问题。 - Khaled Alhayek

6
我遇到了同样的错误并解决了它。在我的情况下,我认为是因为我将Django默认模式设置为 django ,当运行 $ python manage.py test 时,测试函数尝试将一些表迁移到数据库 test 架构 django ,但是那里还没有创建 django 模式。因此解决方案要么是(1)允许Django测试功能在 public 模式中进行搜索,或者是(2) 在没有测试数据库的情况下运行单元测试

从这个问题的被接受答案来看,我想我的情况与问题不同。但我认为两者都是由于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
            },
        },
    }

1
这个对我有用,谢谢! - comfortchambeshi

5

我觉得回答可能有点晚了,但对我有用的方法很简单,只需按照以下步骤操作:

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

3

这对我很有帮助。

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

1

我最近遇到了类似的问题,结果发现尝试创建对象的用户/角色没有默认模式定义。为了解决这个问题,我执行了以下操作之一或两者都执行(我记不清哪一个):

  • 添加search_path:ALTER ROLE <user_name> SET search_path TO schema1, schema2
  • 使用currentSchema参数连接到数据库

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接