首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django系统检查、迁移和测试在本地通过,但在Docker CI/CD环境中失败

Django系统检查、迁移和测试在本地通过,但在Docker CI/CD环境中失败
EN

Stack Overflow用户
提问于 2019-06-07 06:08:52
回答 1查看 1.5K关注 0票数 5

问题

老实说,我只是把这件事搞砸了,因为在问这个问题之前,我已经用尽了所有可能的途径。我不知道这里有什么问题。

我有一个Django应用程序,它可以很好地在本地运行。我可以进行迁移。我已经在本地开发了这方面的详细内容,并且在模型、测试或任何特性方面都没有任何问题。

这里的问题是,第二次使用GitLab的CI/CD Runner并执行与我在本地执行的步骤完全相同的步骤,我就得到了这个输出。

代码语言:javascript
复制
ERRORS:
piano_gym_api.LearnerEnrolledLesson.enrolled_course: (fields.E300) Field defines a relation with model 'piano_gym_api.LearnerEnrolledCourse', which is either not installed, or is abstract.
piano_gym_api.LearnerEnrolledLesson.enrolled_course: (fields.E307) The field piano_gym_api.LearnerEnrolledLesson.enrolled_course was declared with a lazy reference to 'piano_gym_api.learnerenrolledcourse', but app 'piano_gym_api' doesn't provide model 'learnerenrolledcourse'.
piano_gym_api.LearnerEnrolledLesson.enrolled_school: (fields.E300) Field defines a relation with model 'piano_gym_api.LearnerEnrolledSchool', which is either not installed, or is abstract.
piano_gym_api.LearnerEnrolledLesson.enrolled_school: (fields.E307) The field piano_gym_api.LearnerEnrolledLesson.enrolled_school was declared with a lazy reference to 'piano_gym_api.learnerenrolledschool', but app 'piano_gym_api' doesn't provide model 'learnerenrolledschool'.

环境

我在Django 2.2中使用Python3.7。我的依赖关系如下所示:

代码语言:javascript
复制
certifi==2019.3.9
chardet==3.0.4
coreapi==2.3.3
coreschema==0.0.4
Django==2.2
django-cors-headers==3.0.2
django-extensions==2.1.7
djangorestframework==3.9.4
djangorestframework-jwt==1.11.0
gunicorn==19.9.0
idna==2.8
itypes==1.1.0
Jinja2==2.10.1
lxml==4.3.3
MarkupSafe==1.1.1
music21==5.5.0
PyJWT==1.7.1
pytz==2019.1
requests==2.22.0
six==1.12.0
sqlparse==0.3.0
uritemplate==3.0.0
urllib3==1.25.3
whitenoise==4.1.2

我使用的是免费版本的GitLabGitLab Runner

这是一个简单的django项目。有一个项目和一个应用程序。

我的settings.conf的INSTALLED_APPS看起来像这样

代码语言:javascript
复制
# Application definition
INSTALLED_APPS = [
    # Django Default
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # Third-Party Apps
    "corsheaders",
    "django_extensions",
    "rest_framework",
    "rest_framework.authtoken",
    "whitenoise.runserver_nostatic",
    # Custom Apps
    "piano_gym_api",
]

本地运行的步骤

这将使通过

  • pip3 install virtualenv
  • virtualenv -p python3 venv
  • source venv/bin/activate
  • pip3 install -r requirements.txt
  • python3 manage.py makemigrations piano_gym_api
  • python3 manage.py migrate
  • python3 manage.py test

在GitLab CI/CD中运行的步骤

这将使失败

我安装了GitLab Runner

我在根目录中创建了一个.gitlab-ci.yml文件。它所拥有的只是:

代码语言:javascript
复制
stages:
  - test

api-test:
  stage: test
  image: python:3.7
  script:
    - cd piano_gym_back_end
    # Create environment for python
    - pip3 install virtualenv
    - virtualenv -p python3 venv
    - source venv/bin/activate
    - pip3 install -r requirements.txt
    # Set up and run tests
    - python3 manage.py makemigrations piano_gym_api
    - python3 manage.py migrate
    - python3 manage.py test

然后提交分支上的所有内容并运行gitlab-runner exec docker api-test

然后遍历每一件事情并输出

代码语言:javascript
复制
$ python3 manage.py makemigrations piano_gym_api
SystemCheckError: System check identified some issues:

ERRORS:
piano_gym_api.LearnerEnrolledLesson.enrolled_course: (fields.E300) Field defines a relation with model 'piano_gym_api.LearnerEnrolledCourse', which is either not installed, or is abstract.
piano_gym_api.LearnerEnrolledLesson.enrolled_course: (fields.E307) The field piano_gym_api.LearnerEnrolledLesson.enrolled_course was declared with a lazy reference to 'piano_gym_api.learnerenrolledcourse', but app 'piano_gym_api' doesn't provide model 'learnerenrolledcourse'.
piano_gym_api.LearnerEnrolledLesson.enrolled_school: (fields.E300) Field defines a relation with model 'piano_gym_api.LearnerEnrolledSchool', which is either not installed, or is abstract.
piano_gym_api.LearnerEnrolledLesson.enrolled_school: (fields.E307) The field piano_gym_api.LearnerEnrolledLesson.enrolled_school was declared with a lazy reference to 'piano_gym_api.learnerenrolledschool', but app 'piano_gym_api' doesn't provide model 'learnerenrolledschool'.
ERROR: Job failed: exit code 1
FATAL: exit code 1                      

模型

现在我明白了,这是说它在piano_gym_api应用程序中找不到模型。但这没有道理。

这里的模式是:

代码语言:javascript
复制
class LearnerEnrolledLesson(Model):
    is_enrolled = BooleanField(default=True)
    learner = ForeignKey("piano_gym_api.Learner", on_delete=CASCADE)
    # ---
    enrolled_school = ForeignKey("piano_gym_api.LearnerEnrolledSchool", on_delete=CASCADE)
    enrolled_course = ForeignKey("piano_gym_api.LearnerEnrolledCourse", on_delete=CASCADE)
    # ---
    school = ForeignKey(School, on_delete=CASCADE)
    course = ForeignKey(SchoolCourse, on_delete=CASCADE)
    lesson = ForeignKey(SchoolLesson, on_delete=CASCADE)
    order = IntegerField(default=1)

    REQUIRED_FIELDS = ["learner", "school", "course", "lesson", "enrolled_school", "enrolled_course"]

    objects = LearnerEnrolledLessonManager()

    class Meta:
        ordering = ("order",)
        unique_together = ("learner", "school", "course", "lesson", "enrolled_school", "enrolled_course", "order")

我在这里所做的唯一事情就是使用字符串来引用piano_gym_api.LearnerEnrolledSchoolpiano_gym_api.LearnerEnrolledCourse

之所以这样做,是因为这些模型有一个返回LearnerEnrolledLesson的函数,这是一个循环依赖关系,所以我必须引用模型而不使用导入路径。

求助呼吁

我不知道为什么这是失败在我的CI/CD对接环境。我没做什么不同的事。我的settings.py在开发环境和ci/cd环境之间没有变化。步骤是完全一样的。

我在这里可能做错了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-23 19:20:41

我找到了解决这个问题的方法,这是非常微妙的。

首先,我要感谢来自Python不和谐频道的一个名为Python不和谐频道的人。多亏了他们的努力,他们和我一起坐下来,走过了我所经历的一切,我们才能诊断出这一点。

这里的问题很微妙,因为在sqlite3中没有任何问题。然而,当我迁移到postgresql时,问题就出现了。

具体的问题是,我没有制造它,所以我的模型是可用的。

Django需要在路径中存在模型

  • django_project_name/django_app_name/models.py

  • django_project_name/django_app_name/models/

我的目录结构实际上如下所示

代码语言:javascript
复制
├── requirements.txt
├── manage.py
├── django_app_name
│   ├── models
│   │   └── __init__.py
│   ├── urls.py
│   └── versions
│       ├── __init__.py
│       └── v1
│           ├── __init__.py
│           ├── models
│           │   ├── __init__.py
│           │   └── ...
│           └── views
│               ├── __init__.py
│               └── ...
└── django_project_name
    └── ...

这里的问题是,为了创建一个版本化的目录结构,我将模型移动到django_project_name/django_app_name/versions/v1/中。

由于这个原因,Django找不到模型,因为我没有通过models.py文件或Django应用程序中期望的models目录显式地提供它们。

这就是为什么我会得到这样的错误: Django无法找到特定的模型,尽管它们在那里。

要修复这个解决方案,我必须在django_project_name/django_app_name/models/__init__.py文件中导出它们的引用,从而显式地公开它们。

看起来是这样的:

代码语言:javascript
复制
# REQUIRED!!!
# Django requires models that are being used to be exposed in this models
# directory
# Because we have opted to use the `versions` folder for storing the structure
# of our project, that means we need to surface those models explicitly here in
# order to remove the possibility of a missing model during the `makemigrations`
# and `migrate` commands
from django_app_name.versions.v1.models.example_model_one import *
from django_app_name.versions.v1.models.example_model_two import *
from django_app_name.versions.v1.models.example_model_three import *
...

有了这个,我就能让我的模型可以用于makemigrationsmigrate

非常微妙:)

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56488801

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档