Creating models with their relationships

Now, we will create the models that we can use to represent and persist the message categories, messages, and their relationships. Open the api/models.py file and replace its contents with the following code. The lines that declare fields related to other models are highlighted in the code listing. In case you created a new virtual environment, create a new models.py file within the api folder. The code file for the sample is included in the restful_python_chapter_06_01 folder:

from marshmallow import Schema, fields, pre_load 
from marshmallow import validate 
from flask_sqlalchemy import SQLAlchemy 
from flask_marshmallow import Marshmallow 
 
 
db = SQLAlchemy() 
ma = Marshmallow() 
 
 
class AddUpdateDelete():    
    def add(self, resource): 
        db.session.add(resource) 
        return db.session.commit() 
 
    def update(self): 
        return db.session.commit() 
 
    def delete(self, resource): 
        db.session.delete(resource) 
        return db.session.commit() 
 
 
class Message(db.Model, AddUpdateDelete): 
    id = db.Column(db.Integer, primary_key=True) 
    message = db.Column(db.String(250), unique=True, nullable=False) 
    duration = db.Column(db.Integer, nullable=False) 
    creation_date = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), nullable=False) 
    category_id = db.Column(db.Integer, db.ForeignKey('category.id', ondelete='CASCADE'), nullable=False) 
    category = db.relationship('Category', backref=db.backref('messages', lazy='dynamic' , order_by='Message.message')) 
    printed_times = db.Column(db.Integer, nullable=False, server_default='0') 
    printed_once = db.Column(db.Boolean, nullable=False, server_default='false') 
 
    def __init__(self, message, duration, category): 
        self.message = message 
        self.duration = duration 
        self.category = category 
 
 
class Category(db.Model, AddUpdateDelete): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(150), unique=True, nullable=False) 
 
    def __init__(self, name): 
        self.name = name 

First, the code creates an instance of the flask_sqlalchemy.SQLAlchemy class named db. This instance will allow us to control the SQLAlchemy integration for our Flask application. In addition, the instance will provide access to all the SQLAlchemy functions and classes.

Then, the code creates an instance of the flask_marshmallow.Marshmallow class named ma. It is very important to create the flask_sqlalchemy.SQLAlchemy instance before the Marshmallow instance, and therefore, order matters in this case. Marshmallow is a wrapper class that integrates Mashmallow with a Flask application. The instance named ma will provide access to the Schema class, the fields defined in marshmallow.fields, and the Flask-specific fields declared in flask_marshmallow.fields. We will use them later when we declare the schemas related to our models.

The code creates the AddUpdateDelete class that declares the following three methods to add, update, and delete a resource through SQLAlchemy sessions:

  • add: This method receives the object to be added in the resource argument and calls the db.session.add method with the received resource as an argument to create the object in the underlying database. Finally, the code commits the session.
  • update: This method just commits the session to persist the changes made to the objects in the underlying database.
  • delete: This method receives the object to be deleted in the resource argument and calls the db.session.delete method with the received resource as an argument to remove the object in the underlying database. Finally, the code commits the session.

The code declares the following two models, specifically, two classes, as a subclass of both the db.Model, and the AddUpdateDelete classes:

  • Message
  • Category

We specified the field types, maximum lengths, and defaults for many attributes. The attributes that represent fields without any relationship are instances of the db.Column class. Both models declare an id attribute and specify the True value for the primary_key argument to indicate it is the primary key. SQLAlchemy will use the data to generate the necessary tables in the PostgreSQL database.

The Message model declares the category field with the following line:

category = db.relationship('Category', backref=db.backref('messages', lazy='dynamic', order_by='Message.message')) 

The previous line uses the db.relationship function to provide a many-to-one relationship to the Category model. The backref argument specifies a call to the db.backref function with 'messages' as the first value that indicates the name to use for the relation from the related Category object back to a Message object. The order_by argument specifies 'Message.message' because we want the messages for each category to be sorted by the value of the message field in ascending order.

Both models declare a constructor, that is, the __init__ method. This constructor for the Message model receives many arguments and uses them to initialize the attributes with the same names: message, duration, and category. The constructor for the Category model receives a name argument and uses it to initialize the attribute with the same name.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.46.78