Flask SQLAlchemy выдает «NoReferencedTableError» при размещении кодов в структуре пакета - PullRequest
1 голос
/ 12 января 2020

Я изучаю flask и пытаюсь расположить свои коды в «структуре пакета» в соответствии с некоторыми онлайн-уроками. Я собрал несколько минимальных кодов, чтобы повторить мою проблему. Сначала древовидная структура моих кодов:

.
└── test001
    ├── __init__.py
    ├── models.py
    └── views.py

Исходные коды для каждого файла:

" __ init __. Py ":

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SECRET_KEY'] = 'somerandomnumber'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)

from test001 import views

Источник для " models.py ":

from test001 import db,app

class User(db.Model):
    id         = db.Column(db.Integer, primary_key=True)
    username   = db.Column(db.String(20), unique=True, nullable=False)
    email      = db.Column(db.String(120), unique=True, nullable=False)
    password   = db.Column(db.String(60), nullable=False)

    favoritejob_id = db.Column(db.Integer, db.ForeignKey('favoritejob.id'), nullable=True)
    favoritejob    = db.relationship("FavoriteJob", backref=db.backref("users"), lazy=True)

class FavoriteJob(db.Model):
    id   = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20), nullable=False)

    def __repr__(self):
        return f"<FavoriteJob ID={self.id} Name={self.name}>"

Источник для " views.py " (объединение всех маршрутов):

from test001.models import User, FavoriteJob

# @app.route("/register", methods=['GET', 'POST'])
# def register():
#    PLACE HOLDER FOR USER REGISTRATION

С кодами выше, я тогда go до python3 оболочки и к следующему:

from test001 import db
db.create_all()

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

---------------------------------------------------------------------------
NoReferencedTableError                    Traceback (most recent call last)
<ipython-input-2-653042798025> in <module>
----> 1 db.create_all()
...
...
~/.local/lib/python3.6/site-packages/sqlalchemy/sql/schema.py in column(self)
   2045                     "foreign key to target column '%s'"
   2046                     % (self.parent, tablekey, colname),
-> 2047                     tablekey,
   2048                 )
   2049             elif parenttable.key not in parenttable.metadata:

NoReferencedTableError: Foreign key associated with column 'user.favoritejob_id' could not find table 'favoritejob' with which to generate a foreign key to target column 'id'

Я сделал довольно долго искал об этой ошибке, но не нашел ничего плохого в models.py. Затем я удалил следующую строку из views.py, которая делает views.py пустым файлом

from test001.models import User, FavoriteJob

Затем «db.create_all ()» начинает работать.

Однако я не могу оставьте views.py пустым, так как я добавлю все маршруты views / url в файл, и мне нужно будет использовать классы User и FavoriteJob.

Я не мог понять, почему строка импорта в views.py будет привести к сбою db.create_all (). Я совершенно новичок в flask и sqlalchemy, так что извините, если что-то явно не так с моей настройкой. Я ценю вашу помощь.

1 Ответ

0 голосов
/ 12 января 2020

Flask -SQLAlchemy определяет имена таблиц из описательных базовых моделей (если вы не определили их самостоятельно). И если имя модели, например, CamelCase, оно устанавливает имя таблицы как camel_case, а не camelcase.

В определениях вашей модели у вас есть связанное поле для User модель - favoritejob_id, что относится к FavoriteJob модели (согласно декларации отношения favoritejob). Поскольку у вас нет явного имени таблицы для модели FavoriteJob, Flask -SQLAlchemy назовет его как favorite_job. Но определение вашего связанного поля имеет:

db.ForeignKey('favoritejob.id')

, поскольку таблица favoritejob не существует, вы получаете сообщение об ошибке (как и ожидалось).


У вас есть пара вариантов для решения этой проблемы:

  • Возможно, самый простой вариант - переименовать имя связанной таблицы:

    db.ForeignKey('favorite_job.id')
    
  • Или дать имя таблицы для FavoriteJob модель как favoritejob:

    class FavoriteJob(db.Model):
        __tablename__ = 'favoritejob'
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...