Ошибка внешнего ключа SQLAlchemy: «Не удалось найти таблицу «пользователь» для объявления.creator_id»Python

Программы на Python
Ответить
Anonymous
 Ошибка внешнего ключа SQLAlchemy: «Не удалось найти таблицу «пользователь» для объявления.creator_id»

Сообщение Anonymous »

Описание проблемы:
Я столкнулся с ошибкой при запуске приложения Flask. Ошибка возникает, когда я пытаюсь войти в систему, и, похоже, она связана с внешним ключом модели Announcement, ссылающимся на модель User. Вот отслеживание ошибок:

Код: Выделить всё

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'announcement.creator_id' could not find table 'user' with which to generate a foreign key to target column 'id'
Соответствующий код:
Вот используемые модели:
Модель пользователя:

Код: Выделить всё

class User(db.Model, UserMixin):
__bind_key__ = 'main'  # Bind to 'main' database
__tablename__ = 'user'
metadata = metadata_main  # Explicit metadata
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
role = db.Column(db.String(20), nullable=False)
is_admin_field = db.Column(db.Boolean, default=False)

def set_password(self, password):
self.password_hash = generate_password_hash(password)

def check_password(self, password):
return check_password_hash(self.password_hash, password)

@property
def is_admin(self):
"""Return True if the user is an admin."""
return self.role == 'admin'

def get_role(self):
"""Return the role of the user."""
return self.role

def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.role}')"
Модель объявления[/b]:

Код: Выделить всё

class Announcement(db.Model):
__bind_key__ = 'main'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(150), nullable=False)
content = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
created_by = db.Column(db.String(50), nullable=False)

# ForeignKeyConstraint ensures the reference to user.id in 'main' database
creator_id = db.Column(db.Integer, nullable=False)
__table_args__ = (
ForeignKeyConstraint(
['creator_id'],
['user.id'],
name='fk_creator_user_id',
ondelete='CASCADE'
),
)

def __repr__(self):
return f""
Где был объявлен модуль:

Код: Выделить всё

# school_hub/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_migrate import Migrate

# Initialize extensions
db = SQLAlchemy()
login_manager = LoginManager()
migrate = Migrate()

def create_app():
app = Flask(__name__)

# Configurations
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:Root1234!@localhost/school_hub'
app.config['SECRET_KEY'] = '8d8a72493996de3050b75e0737fecacf'
app.config['SQLALCHEMY_BINDS'] = {
'main': 'mysql+pymysql://root:Root1234!@localhost/main_db',
'teacher_db': 'mysql+pymysql://root:Root1234!@localhost/teacher_database',
'student_db': 'mysql+pymysql://root:Root1234!@localhost/student_database',
}
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# Initialize extensions with the app
db.init_app(app)
login_manager.init_app(app)
migrate.init_app(app, db)

# Set up Flask-Login user loader
from .models import User  # Import User model here to ensure it's loaded

@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))

# Register Blueprint
from .routes import main
app.register_blueprint(main)

# Ensure app context is pushed before calling db.create_all()
with app.app_context():
# Create all tables for the 'main' database
db.create_all()  # This will create tables for the default 'main' database

# Explicitly create tables for the 'teacher_db' and 'student_db'
from .models import Teacher, Student, User  # Ensure models are imported

# Create tables for 'teacher_db'
Teacher.metadata.create_all(bind=db.get_engine(app, bind='teacher_db'))

# Create tables for 'student_db'
Student.metadata.create_all(bind=db.get_engine(app, bind='student_db'))

return app
Моя среда:
  • Flask: последняя версия
  • Flask-SQLAlchemy: последняя версия
  • SQLAlchemy: последняя версия
  • Python: последняя версия
Мой вопрос:
Почему SQLAlchemy не может найти таблицу пользователя, даже если имя таблицы соответствует ссылке на внешний ключ? Как устранить эту ошибку?
Дополнительный контекст:
Я использую Flask-Migrate для миграции баз данных. Модель User привязана к основной базе данных, а модель Announcement ссылается на эту таблицу. Ошибка возникает, когда SQLAlchemy пытается создать ограничение внешнего ключа и не может найти таблицу user.
Что я пробовал?
< ol>
[*]Обеспечение правильной привязки к базе данных:
  • Я убедился, что обе модели заданы явно __bind_key__ = 'main', чтобы связать их с одним и тем же базу данных.
[*]Обеспечение правильной ссылки на внешний ключ:
  • Модель Announcement имеет внешний ключ, ссылающийся на столбец id модели User:

    Код: Выделить всё

    creator_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    
  • Я проверил, что модель User правильно привязана к «main» и таблица user существует.
[*]Инициализация базы данных:
  • Я позаботился о том, чтобы таблицы создавались в правильном порядке: таблица User создавалась перед Таблица объявлений из-за ограничения внешнего ключа.
[*]Обработка ошибок и предложения :
  • Я проверил, что модели «Пользователь» и «Объявление» правильно импортированы и инициализированы. li>
    Я подтвердил, что ссылка на внешний ключ должна работать, поскольку обе модели привязаны к одному и тому же базу данных.
[*]Повторные проверки привязки к базе данных:
  • Я дважды проверил привязку для моделей «Пользователь» и «Объявление», убедившись, что обе используют «main» в качестве ключа привязки.
[*]Потенциал Проблема с отсутствующей таблицей:
  • Ошибка может произойти, если таблица User не видна для SQLAlchemy во время внешнего создание ключа, поэтому я убедился, что таблица User существует и правильно создана, прежде чем запускать миграцию модели Announcement.


Подробнее здесь: https://stackoverflow.com/questions/792 ... ement-crea
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»