Inheritance in flask models

Asked

Viewed 291 times

1

How do I set a class to inherit another class in flask models?

I am 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)

Until then beauty, when I create the Patient class that should inherit User since the patient will be a user, the Patient fields will stop in 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)

No error appears, however after I give the migrate and upgrade the table Patient is not created and the User inherits the Patient fields

1 answer

2

You have to use the resource Polymorphic sqlalchemy

I adapted your code into a single "file" to exemplify the operation, just copy, change the connection settings to the database and run.

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 execution snippet (__main__), you’ll notice that I used the specific classes of each type to create the instances, if your goal is to use the attribute tipo you can use the standard Factory for such.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.