Getting started with Flask (10): Flask uses SQLAlchemy

11.SQLAlchemy

11.1 Introduction

SQLAlchemy is a Python SQL toolkit and object-relational mapper that gives application developers the power and flexibility of SQL. It provides a complete set of enterprise-level persistence patterns designed for efficient and high-performance database access, adapted into the simple Python domain language.
SQLAlchemy is an ORM (Object Relational Mapper) framework in the Python world. It has two main components: SQLAlchemy ORM and SQLAlchemy Core.

img

11.2 Installation

pip install SQLAlchemy

11.3 Basic usage

create table

The class uses the declarative style and requires at least one __tablename__ attribute to define the name of the database table, and at least one Column is the primary key

# SQLAlchemy练习
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, UniqueConstraint, Index
from sqlalchemy.ext.declarative import declarative_base
# declarative_base类维持了一个从类到表的关系,通常一个应用使用一个base实例,所有实体类都应该继承此类对象

Base = declarative_base()

# 类使用声明式至少需要一个__tablename__属性定义数据库表名字,并至少一Column是主键
# 创建单表
class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(32))
    extra = Column(String(16))


def init_db():
    # 数据库链接引擎
    engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)
    # 创建表
    Base.metadata.create_all(engine)

def drop_db():
    engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)
    # 删除表
    Base.metadata.drop_all(engine)

if __name__ == "__main__":
    init_db()
    # drop_db()

insert data

# SQLAlchemy练习
import models
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)

se = sessionmaker(bind=engine)
session = se()

u1 = models.User(name='a1', extra='aa')
u2 = models.User(name='a2', extra='bb')

session.add(u1)
session.add(u2)


session.commit()
# session.rollback() # 回滚

session.rollback() means rollback

11.4 Connection

SQLAlchemy represents an engine's source as a URI with optional string parameters setting engine options. The form of the URI is:

dialect+driver://username:password@host:port/database

Many parts of this string are optional. If no drive is specified, a default is chosen (make sure to not include the + in this case).

Postgres:

postgresql://scott:tiger@localhost/mydatabase

MySQL:

mysql://scott:tiger@localhost/mydatabaseOracle:

oracle:

//scott:tiger@127.0.0.1:1521/sidname

SQLite (note the four slashes at the beginning):

sqlite:absolute/path/to/foo.db

11.5 Data Types

Write picture description here

SQLAlchemy column options:

img

11.6 Execute native SQL

from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)

# 执行SQL
cur = engine.execute(
    "select * from users"
)

# 获取第一行数据
re1 = cur.fetchone()
# 获取第n行数据
# re2 = cur.fetchmany(2)
# 获取所有数据
re3 = cur.fetchall()

print(re3)
# 注意:当执行fetchone()后,数据已经被去除一条了,即使fetchall(),取出的数据也是从第二条数据开始的

engine.execute uses the database connection pool by default, and can also use DBUtils + pymysql as the connection pool

11.7 Insert data

Create the following table for subsequent additions, deletions, modifications, and queries.

models2.py

# sqlalchemy创建多个关联表
from sqlalchemy import create_engine
from sqlalchemy import Column, Integer, String, UniqueConstraint, Index, DateTime, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
import datetime


Base = declarative_base()


class Classes(Base):
    __tablename__ = 'classes'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String(32), nullable=False, unique=True)


class Student(Base):
    __tablename__ = 'student'
    id = Column(Integer, primary_key=True, autoincrement=True)
    username = Column(String(32), nullable=False, unique=True)
    password = Column(String(32), nullable=False)
    ctime = Column(DateTime, default=datetime.datetime.now)  # 注意now后不要加()

    # 外键:对应的班级
    class_id = Column(Integer, ForeignKey('classes.id'))


class Hobby(Base):
    __tablename__ = 'hobby'
    id = Column(Integer, primary_key=True, autoincrement=True)
    caption = Column(String(32), default='篮球')

# 建立多对多的关系
class Student2Hobby(Base):
    __tablename__ = 'student2hobby'
    id = Column(Integer, primary_key=True, autoincrement=True)
    student_id = Column(Integer, ForeignKey('student.id'))
    hobby_id = Column(Integer, ForeignKey('hobby.id'))

    # 增加联合唯一索引
    __table_args__ = (
        UniqueConstraint('student_id', 'hobby_id', name='uni_student_id_hobby_id'),
    )


def init_db():
    # 数据库链接引擎
    engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)
    # 创建表
    Base.metadata.create_all(engine)

def drop_db():
    engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)
    # 删除表
    Base.metadata.drop_all(engine)

if __name__ == "__main__":
    init_db()
    # drop_db()

After the table is created above, the insert operation is started:

# sqlalchemy的增删改查

import models2
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)

se = sessionmaker(bind=engine)
session = se()

# 单条增加
# c1 = models2.Classes(name='python入门')
# session.add(c1)
# session.commit()
# session.close()


# 多条增加
# c2 = [
#     models2.Classes(name='python进阶'),
#     models2.Classes(name='python高级'),
#     models2.Classes(name='python web')
# ]
# session.add_all(c2)
# session.commit()
# session.close()

11. 8 Deletion and modification operations

# sqlalchemy的增删改查

import models2
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)

se = sessionmaker(bind=engine)
session = se()



# 删除
# session.query(models2.Classes).filter(models2.Classes.id > 2).delete()
# session.commit()


# 修改
# session.query(models2.Classes).filter(models2.Classes.id > 2).update({"name" : "099"})
session.query(models2.Classes).filter(models2.Classes.id > 2).update({
    
    models2.Classes.name: models2.Classes.name + "099"}, synchronize_session=False)
synchronize_session = False  # 对字段执行字符串操作
# session.query(models2.Classes).filter(models2.Classes.id > 2).update({"num": models2.Classes.num + 1}, synchronize_session="evaluate")
# synchronize_session = 'evaluate'  # 对字段执行数值型操作
session.commit()

11.9 Query

Reference: Flask-SQLAlchemy - Wu Peiqi - Blog Park (cnblogs.com)

1. The following methods all return a new query and need to be used with the executor.

filter(): Filtering, more powerful, multi-table association query.
filter_by(): Filtering, generally used in filtering scenarios of single table query.

order_by(): sorting. The default is ascending order, descending order needs to import package: from sqlalchemy import * . Then introduce the desc method. For example, order_by(desc("email")). Sort in descending order of mailbox letters.

group_by(): grouping.

2. The following are some commonly used actuators: use with the above filter.

get(): Get the function whose id is equal to a few.

For example: query the object with id=1.

get(1), remember: there is no "id=" in the brackets, and it is ok to directly pass in the value of id. Because the function of this function is to query the object whose primary key is equal to a few.

all(): Query all data.

first(): Query the first data.

count(): returns the number of query results.

paginate(): paging query, returns a pagination object.

paginate (parameter 1, parameter 2, parameter 3) => parameter 1: the current page; parameter 2: how many records are displayed on each page; parameter 3: whether to return an error.

The returned paging object has three properties: items: get the result of the query, pages: get how many pages there are in total, page: get the current page.

3. Commonly used logic symbols:

You need to import the package to use: from sqlalchemy import *

not_, and_, or_ and the sorting desc mentioned above.

The commonly used built-in ones are: in_: Indicates what range a certain field is in.

4. Some database queries for other relationships:

endswith(): What ends with.

startswith(): What to start with.

contains(): contains

# sqlalchemy的增删改查

import models2
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import text


# 数据库链接引擎
engine = create_engine("mysql+pymysql://root:[email protected]:3306/flask01?charset=utf8", max_overflow=5)

se = sessionmaker(bind=engine)
session = se()


# 查询

r1 = session.query(models2.Classes).all()  # 返回models2.Classes对象

# label相当于sql里的as,取别名,后面结果集使用也是使用别名
r2 = session.query(models2.Classes.name.label('xx'), models2.Classes.name).all()

# 查询课程名字为python入门的课程
r3 = session.query(models2.Classes).filter(models2.Classes.name == "python入门").all()
# 也可使用filter_by,注意filter_by的传参和filter不一样
r4 = session.query(models2.Classes).filter_by(name='python入门').all()

# 查询课程名字为python入门的课程的第一个
r5 = session.query(models2.Classes).filter_by(name='python入门').first()

# 查询id<2且课程名字为python入门的课程
r6 = session.query(models2.Classes).filter(text("id<:value and name=:name")).params(value=2, name='python入门').order_by(models2.Classes.id).all()

# from_statement相当于子查询
r7 = session.query(models2.Classes).from_statement(text("SELECT * FROM Classes where name=:name")).params(name='python入门').all()

print(r7)
session.close()
# 注意:除了r2,其他结果都为models2.Classes对象
# 条件
ret = session.query(Users).filter_by(name='alex').all()
ret = session.query(Users).filter(Users.id > 1, Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.between(1, 3), Users.name == 'eric').all()
ret = session.query(Users).filter(Users.id.in_([1,3,4])).all()
ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all()
ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='eric'))).all()
from sqlalchemy import and_, or_
ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
ret = session.query(Users).filter(or_(Users.id < 2, Users.name == 'eric')).all()
ret = session.query(Users).filter(
    or_(
        Users.id < 2,
        and_(Users.name == 'eric', Users.id > 3),
        Users.extra != ""
    )).all()


# 通配符
ret = session.query(Users).filter(Users.name.like('e%')).all()
ret = session.query(Users).filter(~Users.name.like('e%')).all()

# 限制
ret = session.query(Users)[1:2]

# 排序
ret = session.query(Users).order_by(Users.name.desc()).all()
ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc()).all()

# 分组
from sqlalchemy.sql import func

ret = session.query(Users).group_by(Users.extra).all()
ret = session.query(
    func.max(Users.id),
    func.sum(Users.id),
    func.min(Users.id)).group_by(Users.name).all()

ret = session.query(
    func.max(Users.id),
    func.sum(Users.id),
    func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2).all()

# 连表

ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()
# 默认使用外键进行连表
ret = session.query(Person).join(Favor).all()  # 内连接

ret = session.query(Person).join(Favor, isouter=True).all() # 左连接


# 组合
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all()

q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all()

Reference:
https://blog.csdn.net/u011146423/article/details/87605812

​Python Development [Part 19]: Python Operation MySQL - Wu Peiqi - Blog Garden (cnblogs.com)

​SQLAlchemy Study Notes_JP.Zhang-CSDN Blog

Guess you like

Origin blog.csdn.net/qq_43745578/article/details/129188691