Flask SQLAlchemy не может найти связанный класс - PullRequest
0 голосов
/ 09 февраля 2020

Об этой ошибке довольно много сообщений, но ни один из ответов не относится ко мне, насколько я вижу, мой код уже соответствует ответам в других сообщениях.

Я импортирую свою полную модель и он имеет все классы, столбцы и определенные отношения. В моем коде самого первого оператора, который я выполняю, я получаю эту ошибку:

InvalidRequestError: При инициализации сопоставленного класса сопоставления Application-> application в выражении «Version» не удалось найти имя («name» Version ' не определен"). Если это имя класса, подумайте о том, чтобы добавить эту связь () в класс после того, как были определены оба зависимых класса.

Интересно, что первое выполненное мной выражение, которое «вызывает» ошибку, даже не затрагивает классы в сообщении. Для записи это user_mk = User.query.filter_by(user_name='mk').first().

Часть модели, в которой ошибки являются простыми отношениями 1-M.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
...etc...
app = Flask(__name__)
app.config.from_object(TestConfig)  
db = SQLAlchemy(app)

class User(UserMixin, db.Model)
    __bind_key__ = 'app'
    __tablename__ = 'user'

...etc...

class Version(db.Model):
    __bind_key__ = 'app'
    __tablename__ = 'version'

    version_id = db.Column(db.Integer, primary_key=True)
    version_number = db.Column(db.Integer, nullable=False)
    release_number = db.Column(db.Integer, nullable=False)
    modification_number = db.Column(db.Integer, nullable=False, server_default=db.text("0"))
    test_status = db.Column(db.Integer, index=True)
    lifecycle = db.Column(db.Text, index=True, server_default=db.text("\"Current\""))
    timestamp = db.Column(db.DateTime, server_default=db.text("CURRENT_TIMESTAMP"))
    notes = db.Column(db.Text)

class Application(db.Model):
    __bind_key__ = 'app'
    __tablename__ = 'application'

    application_id = db.Column(db.Integer, primary_key=True)
    application_name = db.Column(db.Text)
    version_id = db.Column(db.ForeignKey('version.version_id'), index=True)
    description = db.Column(db.Text)
    notes = db.Column(db.Text)

    version = db.relationship('Version')

Я не могу понять, как SQLAlchemy не может "увидеть" Version класс из Application класса. Что я делаю неправильно?

ОБНОВЛЕНИЕ В соответствии с предложением в ответе ниже возникает другая ошибка.

sqlalchemy.ex c .InvalidRequestError: Один или несколько сопоставителей не удалось инициализировать - не может продолжить инициализацию других картографов. Инициирующий маппер: 'mapped class Version-> version'. Первоначальное исключение было следующим: не удалось определить условие соединения между родительскими / дочерними таблицами для отношений Version.applications - нет внешних ключей, связывающих эти таблицы. Убедитесь, что ссылки на столбцы связаны с ForeignKey или ForeignKeyConstraint, или укажите выражение «primaryjoin».

Код, который я пробовал:

class Version(db.Model):
    __bind_key__ = 'app'
    __tablename__ = 'version'

    version_id = db.Column(db.Integer, primary_key=True)
    version_number = db.Column(db.Integer, nullable=False)
    release_number = db.Column(db.Integer, nullable=False)
    modification_number = db.Column(db.Integer, nullable=False, server_default=db.text("0"))
    test_status = db.Column(db.Integer, index=True)
    lifecycle = db.Column(db.Text, index=True, server_default=db.text("\"Current\""))
    timestamp = db.Column(db.DateTime, server_default=db.text("CURRENT_TIMESTAMP"))
    notes = db.Column(db.Text)

    applications = db.relationship('Application', 
                    backref='version',
                    primaryjoin='Version.version_id == Application.version_id',
                    )

class Application(db.Model):
    __bind_key__ = 'app'
    __tablename__ = 'application'

    application_id = db.Column(db.Integer, primary_key=True)
    application_name = db.Column(db.Text)
    version_id = db.Column(db.ForeignKey('version.version_id'), index=True)
    description = db.Column(db.Text)
    notes = db.Column(db.Text)

ANSWER Спасибо @djnz. Ответ, который работает, заключается в следующем, но не ясно, почему. Обратите внимание, что предложение primaryjoin в Version было заменено предложением foreign_keys.

class Version(db.Model):
    __bind_key__ = 'app'
    __tablename__ = 'version'

    version_id = db.Column(db.Integer, primary_key=True)
    version_number = db.Column(db.Integer, nullable=False)
    release_number = db.Column(db.Integer, nullable=False)
    modification_number = db.Column(db.Integer, nullable=False, server_default=db.text("0"))
    test_status = db.Column(db.Integer, index=True)
    lifecycle = db.Column(db.Text, index=True, server_default=db.text("\"Current\""))
    timestamp = db.Column(db.DateTime, server_default=db.text("CURRENT_TIMESTAMP"))
    notes = db.Column(db.Text)

    applications = db.relationship('Application', 
                    backref='version',
                    foreign_keys="Application.version_id",
                    )

class Application(db.Model):
    __bind_key__ = 'app'
    __tablename__ = 'application'

    application_id = db.Column(db.Integer, primary_key=True)
    application_name = db.Column(db.Text)
    version_id = db.Column(db.ForeignKey('version.version_id'), index=True)
    description = db.Column(db.Text)
    notes = db.Column(db.Text)

1 Ответ

1 голос
/ 10 февраля 2020

Это, вероятно, там, где требуется backref или back_populates. Они используются SQLAlchemy для сопоставления отношений.

Использование backref (для вашей модели Version):

applications = db.relationship("Version", backref="version")

Это то же самое, что и запись:

# Version model:
applications = db.relationship("Application", back_populates="version")

# Application model:
version = db.relationship("Version", backref="applications")

Затем это сопоставление добавляет в модель родительскую / дочернюю ссылку, например my_version.applications или my_application.version

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...