После помещения проекта в контейнер не получается создать базу данных при инициализации приложения
Я создал проект на flask и структурировал его, после внутри приложения tasks создал init.py, и в нем написал create_app. Не знаю по какой причине но после того как я перенес проект в докер , база данных не хочет создаваться. Файл с базой у меня уже существовал, но я также не мог получить доступ к данным через query от sqlalchemy, выдавало ту же ошибку can't set attribute. Я подумал что проблема в файле базы и удалил ее. Но тут все сложнее и не удается даже создать базу. Файл tasks/models.py
from tasks.apps import db
from datetime import datetime
from passlib.hash import pbkdf2_sha256 as sha256
# Базовая информаци о все х моделях
class BaseInfo(db.Model):
__abstract__ = True
created_date = db.Column(db.DateTime, unique=True, default=datetime.utcnow)
def save_to_db(self):
db.session.add(self)
db.session.commit()
# Информация о модели пользователя
class UserModel(BaseInfo):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30), unique=True, nullable=False)
fullname = db.Column(db.String(30), nullable=True)
email = db.Column(db.String(40), unique=True, nullable=False)
password = db.Column(db.String(30), nullable=False)
def __repr__(self):
return f'<User> : {self.username}'
# Поиск в базе данных по имени пользователя
@classmethod
def find_by_username(cls, username):
return cls.query.filter_by(username=username).first()
# Возвращает список всех пользователей и ихи паролей
@classmethod
def return_all(cls):
def to_json(x):
return {
'username': x.username,
}
return {'users': list(map(lambda x: to_json(x), cls.query.all()))}
# Удаляет всех пользователей
@classmethod
def delete_all(cls):
try:
num_rows_deleted = db.session.query(cls).delete()
db.session.commit()
return {'message': '{} users deleted'.format(num_rows_deleted)}
except:
return {'message': 'Something went wrong'}
# генерация хеша пароля, нужен для внесения в базу
@staticmethod
def generate_hash(password):
return sha256.hash(password)
# Валидация захешированного пароля и прописанного пользователем
@staticmethod
def verify_hash(password, hash):
return sha256.verify(password, hash)
def is_active(self):
return True
def get_email(self):
return self.email
def is_authenticated(self):
return self.authenticated
def is_anonymous(self):
return False
class RevokedTokenModel(db.Model):
__tablename__ = 'revoked_tokens'
id = db.Column(db.Integer, primary_key=True)
jti = db.Column(db.String(120))
def add(self):
db.session.add(self)
db.session.commit()
# Проверка на вхождение токена в базу
@classmethod
def is_jti_blacklisted(cls, jti):
query = cls.query.filter_by(jti=jti).first()
return bool(query)
class TaskModel(BaseInfo):
__tablename__ = "tasks"
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50), nullable=False)
description = db.Column(db.Text, nullable=True)
def __repr__(self):
return "<Task>: {title}"
def __init__(self, title, description):
self.title = title
self.description = description
Файл tasks/init.py
import os
from flask import Flask
from .apps import db, jwt, login_manager
from flask_jwt_extended import JWTManager
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
def create_app():
app = Flask(__name__)
from .models import TaskModel, UserModel
jwt = JWTManager()
login_manager = LoginManager()
db = SQLAlchemy(app)
app.config.from_object(os.environ['APP_SETTINGS'])
jwt.init_app(app)
login_manager.init_app(app)
with app.test_request_context():
db.create_all()
import tasks.views as module
import tasks.resources as resources
app.register_blueprint(module.module)
app.register_blueprint(resources.api_bp)
return app
Файл Dockerfile
FROM python:3.9.1
WORKDIR /code
ENV APP_SETTINGS=config.DevelopmentConfig
ENV FLASK_APP=manage.py
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
EXPOSE 5000
COPY . .
Файл docker-compose.yml
version: "3.7"
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
command: "python3 manage.py runserver --host=0.0.0.0"
restart: always
Сама ошибка
web_1 | /usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py:812: UserWarning: Neither SQLALCHEMY_DATABASE_URI nor SQLALCHEMY_BINDS is set. Defaulting SQLALCHEMY_DATABASE_URI to "sqlite:///:memory:".
web_1 | warnings.warn(
web_1 | /usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py:833: FSADeprecationWarning: SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and will be disabled by default in the future. Set it to True or False to suppress this warning.
web_1 | warnings.warn(FSADeprecationWarning(
web_1 | Traceback (most recent call last):
web_1 | File "/code/manage.py", line 8, in <module>
web_1 | app = create_app()
web_1 | File "/code/tasks/__init__.py", line 23, in create_app
web_1 | db.create_all()
web_1 | File "/usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 1039, in create_all
web_1 | self._execute_for_all_tables(app, bind, 'create_all')
web_1 | File "/usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 1031, in _execute_for_all_tables
web_1 | op(bind=self.get_engine(app, bind), **extra)
web_1 | File "/usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 962, in get_engine
web_1 | return connector.get_engine()
web_1 | File "/usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 555, in get_engine
web_1 | options = self.get_options(sa_url, echo)
web_1 | File "/usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 570, in get_options
web_1 | self._sa.apply_driver_hacks(self._app, sa_url, options)
web_1 | File "/usr/local/lib/python3.9/site-packages/flask_sqlalchemy/__init__.py", line 914, in apply_driver_hacks
web_1 | sa_url.database = os.path.join(app.root_path, sa_url.database)
web_1 | AttributeError: can't set attribute