В чем разница между declarative_base () и db.Model?

86

Quickstart учебника для Колба-SQLAlchemy плагина пользователи инструктирует для создания моделей таблицы наследования db.Modelкласса, например ,

app = Flask(__main__)
db = SQLAlchemy(app)
class Users(db.Model):
    __tablename__ = 'users'
    ...

Однако учебник по SQLAlchemy и README для бутылки-SQLAlchemy предполагают, что модели таблиц наследуют Baseэкземпляр, созданный из declarative_base().

Base = declarative_base()
class Users(Base):
    __tablename__ = 'users'
    ...

В чем разница между этими двумя подходами?

доктора
источник

Ответы:

84

В исходном коде Flask-SQLAlchemy db.Modelкласс инициализируется следующим образом:

self.Model = self.make_declarative_base()

А вот make_declarative_base()метод:

def make_declarative_base(self):
    """Creates the declarative base."""
    base = declarative_base(cls=Model, name='Model',
                            metaclass=_BoundDeclarativeMeta)
    base.query = _QueryProperty(self)
    return base

_BoundDeclarativeMetaМетаклассом подкласс SQLAlchemy - х DeclarativeMeta, он просто добавляет поддержку для вычисления значения по умолчанию для __tablename__(имя таблицы) , а также ручки привязок.

base.queryСвойство позволяет модели на основе Колба-SQLAlchemy для доступа к объекту запроса , как Model.queryвместо SQLAlchemy - х session.query(Model).

Класс _QueryPropertyзапроса также является подклассом запроса SQLAlchemy. Подкласс Колба-SQLAlchemy добавляет три дополнительных методов запроса , которые не существуют в SQLAlchemy: get_or_404(), first_or_404()и paginate().

Я считаю, что это единственные различия.

Мигель
источник
1
Я просто искал это сегодня для этого приложения, которое я создавал в течение года или около того, изначально основанного на вашем «Руководстве по Mega Flask», в котором используется db.Model, а не явно используется Base = Declarative_Base. Я запутался, потому что все мои модели явно используют расширение Declarative, но я никогда не вызывал declarative_base (). Спасибо за отличное объяснение!
Chockomonkey
Можно ли использовать db.Model в одной модели пользователя и базу в модели адреса. Например: - класс User (db.Model), класс Address (Base)?
Саиф Али Каредиа
Не уверен, но я предполагаю, что некоторые вещи не сработают. Flask-SQLAlchemy добавляет некоторое поведение к базе в db.Modelклассе, поэтому любые модели, которые наследуются непосредственно от декларативной базы, не будут иметь этого.
Мигель