问题
老实说,我只是把这件事搞砸了,因为在问这个问题之前,我已经用尽了所有可能的途径。我不知道这里有什么问题。
我有一个Django应用程序,它可以很好地在本地运行。我可以进行迁移。我已经在本地开发了这方面的详细内容,并且在模型、测试或任何特性方面都没有任何问题。
这里的问题是,第二次使用GitLab的CI/CD Runner并执行与我在本地执行的步骤完全相同的步骤,我就得到了这个输出。
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。我的依赖关系如下所示:
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我使用的是免费版本的GitLab和GitLab Runner。
这是一个简单的django项目。有一个项目和一个应用程序。
我的settings.conf的INSTALLED_APPS看起来像这样
# 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 virtualenvvirtualenv -p python3 venvsource venv/bin/activatepip3 install -r requirements.txtpython3 manage.py makemigrations piano_gym_apipython3 manage.py migratepython3 manage.py test在GitLab CI/CD中运行的步骤
这将使失败
我安装了GitLab Runner
我在根目录中创建了一个.gitlab-ci.yml文件。它所拥有的只是:
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。
然后遍历每一件事情并输出
$ 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应用程序中找不到模型。但这没有道理。
这里的模式是:
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.LearnerEnrolledSchool和piano_gym_api.LearnerEnrolledCourse。
之所以这样做,是因为这些模型有一个返回LearnerEnrolledLesson的函数,这是一个循环依赖关系,所以我必须引用模型而不使用导入路径。
求助呼吁
我不知道为什么这是失败在我的CI/CD对接环境。我没做什么不同的事。我的settings.py在开发环境和ci/cd环境之间没有变化。步骤是完全一样的。
我在这里可能做错了什么?
发布于 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/我的目录结构实际上如下所示
├── 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文件中导出它们的引用,从而显式地公开它们。
看起来是这样的:
# 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 *
...有了这个,我就能让我的模型可以用于makemigrations和migrate。
非常微妙:)
https://stackoverflow.com/questions/56488801
复制相似问题