Как решить проблему циклического импорта SQL alchemy

avatar
Subhayan Bhattacharya
8 апреля 2018 в 09:08
809
0
0

Ниже приведен пример кода для моего проекта flask sqlalchemy. Ниже приведен фрагмент структуры моего проекта.

project structure

Ниже приведены коды моих проблем:

main.py:

from application import app
from application.database import db

@app.before_first_request
def create_tables():
    db.create_all()

if __name__ == "__main__":
    db.init_app(app)
    app.run(debug=True)

application/init.py

__package__ = "application"

from flask import Flask,session
from os import urandom
from config import BaseConfig
import logging.config
app = Flask(__name__,template_folder='templates')

from models.user_model import Users
from models.question_model import Questions

from views import *

app.config.from_object(BaseConfig)
log_config = app.config['LOGGING_CONFIG']
logging.config.dictConfig(log_config)
logger = logging.getLogger("question_answer_app")
app.logger.handlers = logger.handlers
app.logger.setLevel(logger.level)

модели/user_model.py

__package__ = "application.models"

from ..database import db
from .. import app
from flask import session

class Users(db.Model):
    __table_args__ = {'keep_existing': True}
    id = db.Column(db.Integer,primary_key=True)
    name = db.Column(db.String(20),nullable=False)
    password = db.Column(db.String(20),nullable=False)
    expert = db.Column(db.Boolean,nullable=False)
    admin = db.Column(db.Boolean,nullable=False)


    @classmethod
    def get_by_name(cls,name):
        user = None
        user = cls.query.filter_by(name=name).first()
        return user

    @classmethod
    def get_by_id(cls,id):
        user = None
        user = cls.query.filter_by(id=id).first()
        return user

    @classmethod
    def get_experts(cls):
        experts = []
        for expert in cls.query.filter(cls.expert == True).all():
            temp = {}
            temp['id'] = expert.id
            temp['name'] = expert.name
            app.logger.debug('The expert got from the db is %s',temp['name'])
            experts.append(temp)
        return experts

    @classmethod
    def get_all_nonadmin_users(cls):
        users = []
        users = cls.query.filter_by(admin=False).all()
        return users

    @classmethod
    def get_current_user(cls):
        user_result = None
        if 'username' in session:
            user = session['username']
            user_result = cls.get_by_name(name=user)
        return user_result

    def save_to_db(self):
        db.session.add(self)
        db.session.commit()

models/question_model.py:

__package__ = "application.models"

from ..database import db
from .. import app


class Questions(db.Model):
    __table_args__ = {'keep_existing': True}
    id = db.Column(db.Integer, primary_key=True)
    question_text = db.Column(db.Text, nullable=False)
    answer_text = db.Column(db.Text)
    asked_by_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
    expert_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)

    asked_by_user = db.relationship("Users", foreign_keys=[asked_by_id],lazy='dynamic')
    expert_user = db.relationship("Users", foreign_keys=[expert_id],lazy='dynamic')

    @classmethod
    def get_all_answered_questions_details(cls):
        questions = []
        results = cls.query.filter(cls.answer_text != None).all()
        for result in results:
            temp = {}
            temp['question'] = result.question_text
            temp['asked_by'] = result.asked_by_user.name
            temp['expert'] = result.expert_user.name
            app.logger.debug('Question : %s , asked by : %s and answered by : %s',temp['question'],temp['asked_by'],temp['expert'])
            questions.append(temp)
        return questions

    @classmethod
    def get_question_details(cls,question_id):
        question = Questions.query.filter_by(id=question_id).first()
        return question

    @classmethod
    def view_question_details(cls,question_id):
        question = Questions.query.filter_by(id=question_id).first()
        question_details = {}
        question_details['question'] = question.question_text
        question_details['answer'] = question.answer_text
        question_details['asked_by'] = question.asked_by_user.name
        question_details['expert'] = question.expert_user.name
        return question_details

    @classmethod
    def get_unanswered_questions(cls,expert_id):
        questions = []
        questions = Questions.query.filter(Questions.answer_text != None,Questions.expert_id == expert_id).all()
        for question in questions:
            temp = {}
            temp['questions_text'] = question.question_text
            temp['name'] = question.asked_by_user.name
            questions.append(temp)
        return questions


    def save_to_db(self):
        db.session.add(self)
        db.session.commit()

представления/index.py

__package__ = "application.views"

from .. import app,Users,Questions
from flask import render_template,redirect,url_for


@app.route('/')
def index():
    app.logger.debug("Inside index route")
    user_details = Users.get_current_user()
    results = Questions.get_all_answered_questions_details()
    app.logger.debug("Exiting index route")
    return render_template('home.html',user=user_details,results=results)

Теперь, когда я попал на первый маршрут: http://127.0.0.1:5000

Я получаю следующую ошибку:

sqlalchemy.exc.InvalidRequestError InvalidRequestError: для пути «Пользователи» в реестре этой декларативной базы найдено несколько классов. Пожалуйста, используйте полный путь к модулю.

Может кто-нибудь указать, где я ошибаюсь.

Это сводит меня с ума. Заранее большое спасибо.

Источник
metmirr
8 апреля 2018 в 10:06
0

В question_model.py поместите имя user_model перед Users для обеих строк db.relationship("user_model.Users", ..). Вы определили модели в разных модулях, поэтому это вызывает проблему. Поместите имя модуля при создании отношения.

Subhayan Bhattacharya
8 апреля 2018 в 10:41
0

Все та же ошибка: InvalidRequestError: найдено несколько классов для пути «user_model.Users» в реестре этой декларативной базы. Пожалуйста, используйте полный путь к модулю.

metmirr
8 апреля 2018 в 10:47
0

Тогда ознакомьтесь с этими ответами: coderhelper.com

Ответы (0)