Конструктор Flask-SQLAlchemy

в учебнике Flask-SQLAlchemy определен конструктор для модели User:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

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


class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, username, email):
        self.username = username
        self.email = email

для таблицы с двумя столбцами, которая может быть приемлемой, но что делать, если у меня есть таблицы с 10 + столбцами? do конструкторы имеют, которые нужно определять каждый раз, когда я определяю новую модель?

Ответ 1

В большинстве случаев отсутствие определения конструктора в классе модели дает правильное поведение.

Класс базовой модели Flask-SQLAlchemy (который также является декларативным базовым классом SQLAlchemy) определяет конструктор, который просто принимает **kwargs и сохраняет все заданные аргументы, поэтому нет необходимости определять конструктор.

Если вам нужно определить конструктор для инициализации определенной модели, сделайте это следующим образом:

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120), unique=True)

    def __init__(self, **kwargs):
        super(User, self).__init__(**kwargs)
        # do custom initialization here

Позволяя базовому классу обрабатывать **kwargs вы освобождаете себя от сложности инициализации полей модели.

Ответ 2

Я знаю, что это немного старо, но независимо от того, что это должно быть полезно для кого-то другого с подобной проблемой. Если вы столкнулись с "TypeError: init() принимает ровно 1 аргумент (2 данный)" - это означает, что вам нужно указать ключевые слова при создании объектов для добавления в вашу базу данных следующим образом:

db.session.add(User(username='myname',email='[email protected]',password='mypassword')).

Очень часто приходится сталкиваться с этой небольшой проблемой... но ее трудно обнаружить. Надеюсь, это поможет.

Ответ 3

Вы можете написать конструктор, как хотите, вам просто нужно инициализировать каждое поле, прежде чем пытаться сохранить объект в базе данных.

class User(db.Model):
    ...

user = User()
user.username = 'foo'
user.email = '[email protected]'
db.session.add(user)

Вы также можете инициализировать параметры в конструкторе.

class User(db.Model):
    ...
    def __init__(self, username, email):
        self.username = username
        self.email = email
        self.password = generate_random_password()
        self.last_login = None