gogoWebsite

flask operation MySQL

Updated to 2 days ago

Introduction to sqlalchemy

Object Relationship Mapping:(Object Relational Mapping) is a kind ofProgramming technology, used to implementObject-orientedDifferent in programming languagesType systemofdataConversion between

From the perspective of effect, it creates aprogramming language"Virtual Object Database" used in

Plain language: Mapping of object models and database tables

Why do you need sqlalchemy

As the project becomes larger and larger, a large number of repeated SQL statements will appear in the code by writing native SQL, so the problem will arise.

  1. The reuse rate of SQL statements is not high. The more complex the SQL statements have more conditions and the longer the code, many similar SQL statements will appear.
  2. Many SQL statements are spliced ​​in the business. If the database needs to be changed, these logics need to be modified, and it is easy to miss some SQL modifications.
  3. When writing SQL, it is easy to ignore web security issues, causing hidden dangers

ORM can passkindTo operate the database in a way, without writing native database statements,Table mapping into classes,BundleOKAsExample,BundleFieldsAspropertyWhen ORM executes an object, it will eventually convert the object's operations into native statements in the database. There are many advantages to using ORM.

  1. Ease of use: Using ORM for database development can reduce the probability of repeating SQL statements, and the model written is more intuitive and clear
  2. Low performance consumption: ORM conversion into underlying database operation instructions does have some overhead, but from the actual situation, this loss is very small (less than 5%). As long as there are not strict requirements for performance, and comprehensively considering development efficiency and code reading, the benefits are much greater than the performance loss, and the larger the project, the obvious effect is.
  3. Flexible design: it can easily write complex queries
  4. Portability: SQLAlchemy encapsulates the database implementation of the stratigraphics and supports multiple relational database engines, including the popular MySQL, postgreSQL, etc., which can easily switch databases.
models
ORM
SQL

SQLAlchemy connection to database

from sqlalchemy import create_engine

# Database variables
HOST = "localhost"
PORT = 3306
DATA_BASE = "flask_db"
USER = "root"
PWD = "root"

# mysql driver name://username:password@address:port/database name
DB_URI = f"mysql+pymysql://{USER}:{PWD}@{HOST}:{PORT}/{DATA_BASE}"

engine = create_engine(DB_URI)
# Execute a SQL (virtual)
sql = "select 1"
# Connect to the database
conn = engine.connect()engine = create_engine(DB_URI)
    sql = "create table t_user(id int primary key auto_increment,name varchar(32));"
    conn = engine.connect()
    conn.execute(sql)
rs = conn.execute(sql)
print(rs.fetchone())

Create a table

    engine = create_engine(DB_URI)
    sql = "create table t_user(id int primary key auto_increment,name varchar(32));"
    conn = engine.connect()
    conn.execute(sql)

For data security, you can use the with statement

engine = create_engine(DB_URI)
sql = "create table t_user1(id int primary key auto_increment,name varchar(32));"

with engine.connect() as conn:
    conn.execute(sql)

Model map table structure

  • usedeclarative_baseCreate an ORM base class BASE
  • Use this base class to write your own class. To define__tablename__Class attributes to specify the table name of this model map
  • use.create_all()Map the model to the database
from sqlalchemy import create_engine,Column,Integer,String
from sqlalchemy.ext.declarative import declarative_base

HOST = "localhost"
PORT = 3306
DATA_BASE = "flask_db"
USER = "root"
PWD = "root"
DB_URI = f"mysql+pymysql://{USER}:{PWD}@{HOST}:{PORT}/{DATA_BASE}"

engine = create_engine(DB_URI)

# Create a basic class
Base = declarative_base(engine)

class Person(Base):
    __tablename__ = "t_person"
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(32))
    age = Column(Integer)
    country = Column(String(32))

# Map table structure
Base.metadata.create_all()

Notice
Once the model is mapped to the database using .create_all(), even if the model's fields are changed, it will not be remapping.

sqlalchemy's data addition, deletion, modification and search

Build session object

All ORM operations on the database must be passedsessionImplementation of session objects

from sqlalchemy import create_engine,Column,Integer,String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

HOST = "localhost"
PORT = 3306
DATA_BASE = "flask_db"
USER = "root"
PWD = "root"
DB_URI = f"mysql+pymysql://{USER}:{PWD}@{HOST}:{PORT}/{DATA_BASE}"

engine = create_engine(DB_URI)

# Create a basic class
Base = declarative_base(engine)

class Person(Base):
    __tablename__ = "t_person"
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(32))
    age = Column(Integer)
    country = Column(String(32))
from sqlalchemy.orm import sessionmaker

# Create a session object
Session = sessionmaker(engine)
def create_data_one():# Add a data
    with Session() as session:  # If an error is reported here, please follow the new version of sqlalchemy
        p1 = Person(name="Zhang San",age=18,country="China")
        session.add(p1)
        session.commit()

def create_data_all():  # Add multiple data
    p1 = Person(name="Li Si",age=19,country="America")
    p2 = Person(name="Wang Wu",age=23,country="England")
    with Session() as session:
        session.add_all([p1,p2])
        session.commit()

def query_data():   # Query multiple data and return the name
    with Session() as session:
        all_person = session.query(Person).all()
        for person in all_person:
            print(person.name)

def query_data_one():   # Query the first data (age in the first data)
    with Session() as session:
        person = session.query(Person).first()
        print(person.age)

def query_data_by_params(): # Add filter conditions for query
    with Session() as session:
        # If one uses first, multiple use all
        # p1 = (Person).filter_by(name="Li Si").first() or
        p1 = session.query(Person).filter(Person.name=="Li Si").first()  # is a property, so you need to use a judgment operator instead of assignment
        print(p1.country)   

def update_data():  #Modify data
    with Session() as session:
        p1 = session.query(Person).filter_by(name="Zhang San").first()   # Query statement first
        p1.age = 30
        session.commit()    # Make sure to submit after modification

def delete_data():  # Delete data
    with Session() as session:
        p1 = session.query(Person).filter(Person.name=="Li Si").first()
        session.delete(p1)
        session.commit()

def delete_data_all():
    with Session() as session:
        all_datas = session.query(Person).all()
        for data in all_datas:
            session.delete(data)
        session.commit()
        
if __name__ == '__main__':
    # create_data_one()
    # create_data_all()
    # query_data()
    # query_data_one()
    # query_data_by_params()
    # update_data()
    # delete_data()
    delete_data_all()

Common Column parameters

Set parameters in the field to complete special functions

  • primary_key:True Set a field as the primary key
  • autocrement:True set field to increase automatically
  • default sets a field to the default value
  • unllable specifies whether a field is empty
  • unique specifies whether a field is unique, default False
  • Onupdate will call the value or function specified by this parameter when the data is updated.
from datetime import datetime
from db_utils import *  # Configured mysql file, call it at the moment
from sqlalchemy import Column,Integer,String,DateTime

class News(Base):
    __tablename__ = "t_news"
    id = Column(Integer,primary_key=True,autoincrement=True)
    title = Column(String(32),nullable=False)   # Not allowed to be empty
    read_count = Column(Integer,default=1)  # Reading volume
    create_time = Column(DateTime,default=datetime.now)  # Create time
    update_time = Column(DateTime,default=datetime.now,onupdate=datetime.now)  # Update time
    phone = Column(String(11),unique=True)  # Only account

def create_date():
    new1 = News(phone="18411111111",title="Test column parameters")
    with Session() as session:  # If an error is reported here, upgrade sqlalchemy
        session.add(new1)
        session.commit()

if __name__ == '__main__':
    # .create_all()# Map table structure
    create_date()

Use of query functions

Filter data

There are three types of data that can be passed in the query function.

  • Model name: Specify to find this modelallAttributes (already mentioned above)
  • Properties in a model: You can only find several properties specified in a model
  • Aggregation function:,,,, etc.

funcOn the top, there is actually no aggregate function, but because it does some magic, as long as there are aggregate functions in mysql, they can be called through func


from db_utils import *
from random import randint
from sqlalchemy import Integer,String,Column,func

class Item(Base):
   __tablename__ = "t_item"
   id = Column(Integer,primary_key=True,autoincrement=True)
   title = Column(String(32))
   price = Column(Integer)

def create_data():
   with Session() as sessin:
       for i in range(10): # Randomly generate 10 pieces of data
           item = Item(title = f"Product{i+1}",price=randint(1,100))
           sessin.add(item)
       sessin.commit()

def query_model_name():# Query by class name
   with Session() as session:
       rs = session.query(Item).all()
       for r in rs:
           print(r.price)

def query_model_attr():# Get the specified field query through attributes
   with Session() as session:
       rs = session.query(Item.title,Item.price,Item.id).all()
       for r in rs:
           print(f"Product ID:{r.id}-Product name:{r.title}-Product price:{r.price}")

def query_by_func():
   with Session() as session:
       count = session.query(func.count(Item.id)).first() #Quantity of data
       price_max = session.query(func.max(Item.price)).first()

       print(f" Yes{count}The highest price is{price_max}")

if __name__ == "__main__":
   # .create_all()
   # create_data()
   # query_model_name()
   # query_model_attr()
   query_by_func()

Use of filter filter function

Filtering data is a very important function. The following are some commonly used filter conditions, and these filter conditions can only be implemented through filters.

  • equals:== Precise matching
  • Not equals:! = Complement match
  • like/ilike: case insensitive
  • in: within a certain range
  • Not in: not within a certain range
  • is null: empty
  • is not null: not empty
  • and: Conditional splicing
  • or: one of the conditions that meet one
from sqlalchemy import Column,String,Integer,Float,Text
from random import randint
from db_utils import *
from uuid import uuid4

class Article(Base):
    __tablename__ = "t_article"
    id = Column(Integer,primary_key=True,autoincrement=True)
    title = Column(String(32),nullable=False)
    price = Column(Float,nullable=False)
    content = Column(Text)
    def __repr__(self):
        # A magic method that can print strings instead of addresses directly
        return f"<Articla(title:{self.title} price:{self.price} content:{self.content})>"

# Create a batch of data first
def create_data():
    with Session() as session:
        for i in range(20):
            if i%2 == 0:
                art = Article(title = f"title{i+1}",price=randint(1,100),content=uuid4())
            else:
                art = Article(title=f"TITLE{i+1}",price = randint(1,100))
            session.add(art)
        session.commit()

def query_data():
    with Session() as session:
        # rs = (Article).filter_by(id=1).first() or
        rs = session.query(Article).filter(Article.id==1).first()   # Recommended
        print(rs)

def query_data_equal():
    with Session() as session:

        rs = session.query(Article).filter(Article.title=="title2").first()   # Recommended
        print(rs)

def query_data_equal_not():
    with Session() as session:
        rs = session.query(Article).filter(Article.title!="title2").all()   # Recommended
        print(rs)

def query_data_like():
    # Fuzzy Match
    with Session() as session:
        # select * from t_article where title like "titl%"
        rs = session.query(Article).filter(Article.title.like("%title%")).all()   # Recommended
        for r in rs:
            print(r)

def query_data_in():
    # Fuzzy Match
    with Session() as session:
        # The in_ here is a fixed usage to avoid keyword conflicts in Python
        rs = session.query(Article).filter(Article.title.in_(["title1","title2","title3","title5","title6"])).all()   # Recommended
        for r in rs:
            print(r)

if __name__ == "__main__":
    # .create_all()
    # create_data()
    # query_data()
    # query_data_like()
    query_data_in()

Table of relationships

There are three relationships between tables: one-to-one, one-to-many, and many-to-many
ORM in sqlalchemy can simulate these three relationships
Because the one-to-one and then SQLAlchemy is simulated through a one-to-many method in the underlying layer, let’s first look at the one-to-many relationship:
Foreign keys
Creating a foreign key using sqlalchemy is very simple. Add a field from the table and specify which field of the foreign key of this field is. The fields of foreign keys from the table must be consistent with the primary keys of the primary table. useForeignkeyKeywords.

The constraints of foreign keys are as follows

  • RESTRICT: If there is associated data corresponding to the parent table in the table, deleting the corresponding data corresponding to the parent table will prevent deletion.
  • No ACTION: In MySQL, same as RESTRICT
  • CASCADE: Cascading Deletion
  • SET NULL: The corresponding data of the parent table is deleted, and the corresponding data items of the child table will be set to null

ORM relationship-one to many

sqlalchemy provides arelationship, This class can define attributes, and in the future, when accessing the association table, it can be accessed directly through attribute access.
In addition, it can be done throughbackrefto specify the name of the property for reverse access.

from db_utils import Session,Base
from sqlalchemy import String,Column,Integer,Text,ForeignKey
from sqlalchemy.orm import relationship

class User(Base):
    __tablename__ = "t_user"
    id = Column(Integer,primary_key=True,autoincrement =True)
    uname = Column(String(50),nullable=False,name="name")

    def __repr__(self):
        return f"id={self.id} uname={self.uname}"

# One-to-many ForeignKey puts the more
class News(Base):
    __tablename__ = "t_news"
    id = Column(Integer,primary_key=True,autoincrement =True)
    title = Column(String(32),nullable=False)
    content = Column(Text,nullable=False)
    uid = Column(Integer,ForeignKey("t_user.id"))

    user = relationship("User") # Connect two tables, here is the class name instead of the table name

    def __repr__(self):
        return f"News:id={self.id} content={self.content} uid={self.uid} title={self.title}"

def create_data():
    user = User(uname="zs")
    news1 = News(title="Python",content="Flask",uid=1)
    news2 = News(title="Java",content="Spring",uid=1)
    with Session() as session:
        session.add(user)
        session.commit()
    with Session() as session:
        session.add_all([news1,news2])
        session.commit()

def query_data():
    with Session() as session:
        # select   from t_news left join t_user u  =  where =1;
        news1 = session.query(News).first()
        print(news1.user)   # The user in the News table connects to the User through relationship.
if __name__ == "__main__":
    # .create_all()
    # create_data()
    query_data()

ORM relationship-one to one

In sqlalchemy, if you want to map two models into a one-to-one relationship, you should pass one when specifying a reference in the parent model.uselist=FalseThis parameter is entered. It tells the parent model that when referring to this slave model in the future, it is no longer a list but an object.

from db_utils import Session,Base
from sqlalchemy import Column, ForeignKey,String,Integer
from sqlalchemy.orm import relationship

class LoginUser(Base):
    __tablename__ = "t_user_login"
    id = Column(Integer,primary_key=True,autoincrement=True)
    uname=Column(String(32),nullable=False)
    passwd = Column(String(32),nullable=False)
    user = relationship("User",uselist=False)   # To pass uselist=False in parent table

    def __repr__(self):
        return f"LoginUser:id={self.id} uname={self.uname} passwd={self.passwd}"

# Create a one-to-one relationship, and create a field as a representation of the table (foreign key)
class User(Base):
    __tablename__ = "t_user"
    id = Column(Integer,primary_key = True,autoincrement=True)
    name = Column(String(32),nullable=False,name="name")
    gender = Column(String(1))
    address = Column(String(64))
    login_id = Column(Integer,ForeignKey("t_user_login.id"))

    def __repr__(self):
        return f"User id={self.id} name={self.name} gender={self.gender} address={self.address}"

def create_data():
    login = LoginUser(uname="zs",passwd="123")
    user = User(name="Zhang San",gender="male",address="Confidential")
    login.user = user

    with Session() as session:
        session.add(login)
        session.commit()

def query_data():
    with Session() as session:
        login = session.query(LoginUser).first()
        print(login.user)


if __name__ == "__main__":
    # .create_all()
    # create_data()
    query_data()

ORM Relationship - Many to Many

Many people buy each product, and one person can choose from a variety of products.

  • A many-to-many relationship requires an intermediate table to bind their relationships
  • First define the two models, then use Table to define an intermediate table. The intermediate table generally includes the foreign key fields of the two models, and let them serve as oneJoint primary key
  • Choose one of the two many-to-many models and define onerelationshipAttributes to bind the relationship between these three. When using relationship, you need to pass insecondary=Intermediate table object name
from db_utils import Session,Base
from sqlalchemy.orm import relationship
from sqlalchemy import Column,String,Integer,ForeignKey,Table

"""
 One news can have multiple tags.
 One tag can correspond to multiple news.
 """
# The third table should be placed on top of two models to correlate the two models
news_tag = Table( 
    "t_news_tag",
    Base.metadata,
    Column("news_id",Integer,ForeignKey("t_news.id"),primary_key=True),
    Column("tag_id",Integer,ForeignKey("t_tag.id"),primary_key=True)
)

class New(Base):
    __tablename__ = "t_news"
    id = Column(Integer,primary_key=True,autoincrement=True)
    title = Column(String(32),nullable=False)
    tags = relationship("Tag",backref="newss",secondary=news_tag)   # The third table model name instead of the table name, you can also write another table

    def __repr__(self):
        return f"New: id={self.id} title={self.title}"

class Tag(Base):
    __tablename__ = "t_tag"
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(32),nullable=False)

    def __repr__(self):
        return f"Tag id={self.id} name={self.name}"

def create_data():
    new1  = New(title="This is title 1")
    new2  = New(title="This is Title 2")
    tag1 = Tag(name="Tag 1")
    tag2 = Tag(name="Tag 2")

    new1.tags.append(tag1)
    new1.tags.append(tag2)

    new2.tags.append(tag1)
    
    new2.tags.append(tag2)
    with Session() as session:
        session.add(new1)
        session.add(new2)
        session.commit()

def query_data():
    with Session() as session:
        new = session.query(New).first()
        print(new.tags)

if __name__ == "__main__":
    # .create_all()
    # create_data()
    query_data()

SQLAlchemy cascaded data operation parameters

cascade in relation method at the ORM level

In sqlalchemy, as long as one piece of data is added to the session, the data associated with it can be stored in the database together.

How are these set up? In fact, when using relationship, there is a keyword parameter cascade that can set these properties.

The value of the cascade attribute is:

  • save-updatae: default option. When adding a piece of data, all other related data will be added to the database. This behavior is affected by save-update.
  • delete: indicates whether the data associated with the relationship is also deleted when deleting data in a certain model.
  • delete-orphan: means that when an ORM removes the relational object in the parent table, it will be deleted.
  • merge: default option, when usingWhen merging an object, the object associated with relationship is also merged.
  • expunge: When removing the operation, the associated object will be removed. This operation can only be removed from the session and will not be deleted from the database.
  • all: It is abbreviation for save-update, merge, refresh-expire, expunge, delete.
from unicodedata import name
from db_utils import Session,Base
from sqlalchemy import Column,String,Integer,ForeignKey
from sqlalchemy.orm import relationship

class User(Base):
    __tablename__ = "t_user"
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(32))
    def __repr__(self): 
        return f"User:id={self.id} name={self.name}"

class Article(Base):
    __tablename__ = "t_article"
    id = Column(Integer,primary_key=True,autoincrement=True)
    title = Column(String(32))
    uid = Column(Integer,ForeignKey("t_user.id"))
    user = relationship("User",backref="articles",cascade="save-update")

def create_data():
    Base.metadata.drop_all()    # Delete existing tables
    Base.metadata.create_all()
    # Initialize data
    user = User(name="Zhang San")
    art1 = Article(title="This is title one",uid=1)
    art2 = Article(title="This is title two",uid=1)
    user.articles.append(art1)
    user.articles.append(art2)
    with Session() as session:
        session.add(user)
        session.commit()

if __name__ == "__main__":
    create_data()

Flask-SQLAlchemy usage

flask-sqlalchemy is a plug-in that makes it simple to encapsulate sqlalchemy in flask easier.

pip install flask-sqlalchemy

Key points of using Flask-sqlalchemy

Database connection

Create_engine is no longer used in database initialization

  1. Like sqlalchemy, define the database connection string DB_URI

  2. Pass this defined database throughSQLALCHEMY_DATABASE_URIConfigure tomiddle

    ["SQLALCHEMY_DATABASE_URI"]=DB_URI

  3. useflask_sqlalchemy.SQLAlchemyThis class defines an object and passes the app into

    db=SQLAlchemy(app)

Create an ORM model class

Previously, a base class was initialized through Base=declarative_base() and then inherited. And it's easier in flask-sqlalchemy

  1. It is still the same as using sqlalchemy, defining the model class. Now there is no need to create it with declarative_base(). Instead usedb_ModelAs the base class.
  2. In the model class, Column, String, Integer, and relationship no longer need to be imported. Just use the attribute name under db (
  3. When defining a model, you don't need to write__tablename__, flask will use the name of the current model by default and convert it to lowercase as the name of the table.

    And if this model uses multiple words and uses camel nomenclature, it will add underscores between multiple words to connect (but is not recommended)

Map the ORM model to the database table

After writing the model, to map the model to the database table, use the following code:

  1. Delete database tablesdb.drop_all()
  2. Create a database tabledb.create_all()
Use of session

session is no longer used in flask-sqlalchemysessionmakerCreated, use it directlyThat's right, the operation of this session is the same as before

Add data

There is no difference before adding data, just the session becomes a db property

Query data

  • Single table query: Data query is no longer the previous one(), instead put the query attribute on it, so the query is passedModel name.queryThe method has been queried,querySame as before

  • Multi-table query
    If the search data involves multiple models, you can only use the method (model name).all()

Modify data

There is no difference from before, just session has become a property of db

Delete data

There is no difference from before, just session has become a property of db

Using flask-sqlalchemy

from operator import ne
from flask import Flask, session
from flask_sqlalchemy import SQLAlchemy


app = Flask(__name__)

# Database variables
HOST = "localhost"
PORT = 3306
DATA_BASE = "flask_db"
USER = "root"
PWD = "root"
# mysql driver name://username:password@address:port/database name
DB_URI = f"mysql+pymysql://{USER}:{PWD}@{HOST}:{PORT}/{DATA_BASE}"

app.config["SQLALCHEMY_DATABASE_URI"] = DB_URI
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False    # If you do not add this, a warning will be reported (not an error)

# Connect to the database
db = SQLAlchemy(app)

# Create a model
class User(db.Model):
    __tablename__ = "t_user"    # This is not available, but it is recommended to use it
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    name = db.Column(db.String(32))
    def __repr__(self):
        return f"User:id={self.id},name={self.name}"

class News(db.Model):
    __tablename__ = "t_news"    # This is not available, but it is recommended to use it
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    content = db.Column(db.String(256))
    uid = db.Column(db.Integer,db.ForeignKey("t_user.id"))

    user = db.relationship("User",backref="news")
    def __repr__(self):
        return f"News:id={self.id},content={self.content},uid={self.uid}"    

# Delete table
# db.drop_all()

# Create a table
# db.create_all()

# Add data
def create_data():
    user = User(name="Zhang San")
    news=News(content="This is what Zhang San wrote")
    # Create an association
    user.news.append(news)
    # Add to session
    db.session.add(user)
    db.session.commit()

# Query single table data
def query_data_one():
    users = User.query.all()
    print(users)

# Query multi-table data
def query_data_many():
    rs = db.session.query(User,News.content).join(News,News.uid == User.id).all()
    print(rs)

# Modify data
def update_data():
    user = User.query.first()
    user.name = "Li Si"
    db.session.commit()

# Delete data
def delete_data():
    news = News.query.first()
    db.session.delete(news)
    db.session.commit()

if __name__ == "__main__":
    # create_data()
    # query_data_one()
    # query_data_many()
    # update_data()
    delete_data()

Use of alembic

alembic is a database migration tool that is used to migrate and map ORM models and databases.

Alembic uses a bit similar to git

All alembic commands start with almbic

pip install alembic

Create a model
Initialize the warehouse
Modify the configuration file
Generate migration files
Mapping database
# 
from sqlalchemy import create_engine,Column,String,Integer
from sqlalchemy.ext.declarative import declarative_base

# Database information
HOST = "localhost"
PORT = 3306
DATA_BASE = "flask_db"
USER = "root"
PWD = "root"
# mysql driver name://username:password@address:port/database name
DB_URI = f"mysql+pymysql://{USER}:{PWD}@{HOST}:{PORT}/{DATA_BASE}"

engine = create_engine(DB_URI)
Base = declarative_base(engine)

class User(Base):
    __tablename__ = "t_user"
    id = Column(Integer,primary_key=True,autoincrement=True)
    name = Column(String(32))

initialization

cdIn the current folder
 alembic init Take a folder name

After the command is input, a folder will be generated, and the name of the folder is the name after init

Configuration information

  • Modify in .ini fileInformation (in more than fifty lines), change it to your own database information
  • Modify the content to be mapped in the file
import os,sys
sys.path.append(os.path.dirname(os.path.dirname(__name__)))

import alembic_demo
target_metadata = alembic_demo.Base.metadata

Generate migration files

Enter the command line

 alembic revision --autogenerate -m "model_file"

--autogenerateAutomatic update
-m "model_file"Add prompt information

After executing the command, theversionsFolder generates a migration filedf935ec6b6c2_model_file.py, the alphanumeric preceding is the version numberdf935ec6b6c2

Mapping table structure

Again, although a version information table would appear in the database, the table structure has not been mapped yet and there is no information in the table. Only after the table structure has been mapped, the version number will be
Appears in the information table.

On the command line

alembic upgrade head

Flask-SQLAlchemy and alembic use

Most operations are the same

target_metadata = app_demo.