Inheritance in flask models

1

How do I make a class inherit another class in flask models?

I'm creating the following User class in my models

lass User(db.Model):
__tablename__ = "users"

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, unique=True)
password = db.Column(db.String)
name = db.Column(db.String)
email = db.Column(db.String, unique=True)
tipo = db.Column(db.String(1))

#tipo: N - nutricionista, P - paciente, A - admin  

@property
def is_authenticated(self):
    return True

@property
def is_active(self):
    return True

@property
def is_anonymous(self):
    return False

def get_id(self):
    return str(self.id)

def __init__(self, username, password, name, email, tipo):
    self.username = username
    self.password = password
    self.name = name
    self.email = email
    self.tipo = tipo

def __repr__(self):
    return "<User {0}>".format(self.username)

So, when I'm going to create the Patient class that should inherit User since the patient will be a user, the Patient fields will stop at User

class Paciente(User):
__tablename__ = "pacientes"

dataNascimento = db.Column(db.DateTime)
sexo = db.Column(db.String)
cidade = db.Column(db.String)
profissao = db.Column(db.String)
celular = db.Column(db.String)
objetivo = db.Column(db.String)

def __init__(self, username, password, name, email, dataNascimento, sexo, cidade, profissao, celular, objetivo):
    super().__init__(username, password, name, email, "P")
    self.dataNascimento = dataNascimento
    self.sexo = sexo
    self.cidade = cidade
    self.profissao = profissao
    self.celular = celular
    self.objetivo = objetivo

def __repr__(self):
    return "<Paciente {0}>".format(self.username)

There is no error, but after I migrate and upgrade the Patient table is not created and the User inherits the Patient fields

    
asked by anonymous 03.05.2018 / 14:45

1 answer

1

You have to use the Polymorphic feature of SQLAlchemy

I have tailored your code in a single "file" to exemplify the operation, just copy, change the database connection settings and execute.

from flask.app import Flask
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://<user>:<password>@<host>/<databasename>?client_encoding=utf8'
db = SQLAlchemy(app)

class User(db.Model):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String, unique=True)
    password = db.Column(db.String)
    name = db.Column(db.String)
    email = db.Column(db.String, unique=True)
    tipo = db.Column(db.String(1))

    __mapper_args__ = {
        'polymorphic_on':tipo
    }
    #tipo: N - nutricionista, P - paciente, A - admin  

    @property
    def is_authenticated(self):
        return True

    @property
    def is_active(self):
        return True

    @property
    def is_anonymous(self):
        return False

    def get_id(self):
        return str(self.id)

    def __repr__(self):
        return "<User {0}>".format(self.username)

class Paciente(User):
    __tablename__ = "pacientes"

    id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
    dataNascimento = db.Column(db.DateTime)
    sexo = db.Column(db.String)
    cidade = db.Column(db.String)
    profissao = db.Column(db.String)
    celular = db.Column(db.String)
    objetivo = db.Column(db.String)

    __mapper_args__ = {
        'polymorphic_identity':"P",
    }

    def __repr__(self):
        return "<Paciente {0}>".format(self.username)

class Nutricionista(User):
    __tablename__ = "nutricionistas"
    id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity':"N",
    }

def __repr__(self):
    return "<Nutricionista {0}>".format(self.username)

if __name__ == "__main__":
    db.create_all()
    pac = Paciente(username="joao", email="[email protected]")
    nutri = Nutricionista(username="ana", email="[email protected]")
    db.session.add(pac)
    db.session.add(nutri)
    db.session.commit()
    print(db.session.query(User).all())

TIP: In the runtime (__main__), you will notice that I used the specific classes of each type to create the instances, if your goal is to use the tipo attribute you can use the default factory to do this.

    
08.07.2018 / 01:59