Flash operation Mysql database - Flash Sqlalchemy extension

Posted by samscripts on Sat, 29 Jan 2022 08:51:48 +0100

Official website document

https://flask-sqlalchemy.palletsprojects.com/en/master/quickstart/

Database settings

The relational model database is widely used in Web applications. The relational database stores all data in the table. The table is used to model the entity of the application. The number of columns in the table is fixed and the number of rows is variable. It uses a structured query language. The columns of a relational database define the data attributes of the entities represented in the table. For example, there are name, price, number, etc. in the product list. Flash itself does not limit the choice of database. You can choose either SQL or NOSQL. You can also choose a more convenient SQLALchemy, similar to Django's ORM. SQLALchemy is actually the database www.meimeimeitu8 Com abstraction allows developers to operate the database through Python objects instead of directly dealing with SQL statements. While discarding some performance overhead, it is in exchange for a great improvement in development efficiency.

SQLAlchemy is a relational database framework, which provides the operation of high-level ORM and low-level native database. Flash SQLAlchemy is a flash extension that simplifies SQL alchemy operations.

The following uses mysql as an example.

Create mysql database

1. Log in to the database

mysql -u root -p password

2. Create a database and set the code

create database <Database name> charset=utf8;

3. Display all databases

show databases;

4. The implementation is as follows:

mysql> create database flask_ex charset=utf8;
Query OK, 1 row affected (0.06 sec)

Install the extension of flash Sqlalchemy

pip install -U Flask-SQLAlchemy

python2: to connect to mysql database, you still need to install flash mysql dB

pip install flask-mysqldb

Python 3: to connect to mysql database www.rsxedu.com COM, you still need to install pymysql

pip install pymysql

This chapter begins with Python 3.

Use flask Sqlalchemy to connect to mysql database

To use Flask Sqlalchemy to expand the operation database, you first need to establish a database connection. The database connection is specified by URL, and the database used by the program must be saved to Sqlalchemy of the flash configuration object_ DATABASE_ Uri key.

Compare the database settings in Django and Flask:

Django's database settings:

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # Modify the backend database and use mysql
'NAME': 'mydb', # Set access database name
'USER': 'root', # Access mysql user name
'PASSWORD': 'password', # Set access password
'HOST': 'localhost', # Set access ip address
'PORT': 3306, # Set access port number
}
}

Database settings for flash:

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/flask_ex'

Common SQLAlchemy field types

After reading how to set up the connection database, let's take a look. When using SQLAlchemy to create a data model, the basic field types are as follows:

Type nameTypes in pythonexplain
IntegerintOrdinary integer, usually 32 bits
SmallIntegerintAn integer with a small value range, usually 16 bits
BigIntegerint or longInteger with unlimited precision
FloatfloatFloating point number
Numericdecimal.DecimalOrdinary integer, usually 32 bits
StringstrVariable length string
TextstrVariable length string, which is optimized for long or unlimited length strings
UnicodeunicodeVariable length Unicode string
UnicodeTextunicodeVariable length Unicode string, optimized for long or unlimited length strings
BooleanboolBoolean value
Datedatetime.datetime
Timedatetime.datetimeDate and time
LargeBinarystrBinary file

Common SQLAlchemy column options

Option nameexplain
primary_keyIf True, it represents the primary key of the table
uniqueIf True, it means that duplicate values are not allowed in this column
indexIf True, create an index for this column to improve query efficiency
nullableIf True, null values are allowed; if False, null values are not allowed
defaultDefine default values for this column

Common SQLAlchemy relationship options

Option nameexplain
backrefAdd reverse references to the first mock exam in another model of the relationship.
primary joinExplicitly specify the join conditions used between the two models
uselistIf False, scalar values are used instead of lists
order_bySpecifies how records in the relationship are sorted
secondarySpecifies how records in many to many are sorted
secondary joinSpecify secondary join conditions in many to many relationships when you cannot decide for yourself in SQLAlchemy

There are descriptions of many basic options above. Let's add, delete and modify the database to enhance understanding.

Basic operation of database

In flask Sqlalchemy, insert, modify and delete operations are managed by the database session. Session dB Session representation. Before you write the data to the database, you first add the data to the session and then call the commit() method to submit the session.

Database session is to ensure data consistency and avoid data inconsistency caused by partial update. The commit operation writes all session objects into the database. If an error occurs in the writing process, the whole session will become invalid.

The database session can also be rolled back through dB session. The rollback () method implements the state before the session submits data.

In flask Sqlalchemy, query operation is to manipulate data through query object. The most basic query is to return all the data in the table. You can query the database more accurately through the filter.

Let's create the data model of two tables: user table and role table.

Define model classes in view functions

After reading so many concept descriptions above, let's take a look at how to create a data model and create a data table, as follows:

1. In script 15_SQLAlchemy.py writing to create User and Role data models

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
pymysql.install_as_MySQLdb()

app = Flask(__name__)

class Config(object):
"""configuration parameter"""
# Set the URL to connect to the database
user = 'root'
password = '********'
database = 'flask_ex'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://%s:%s@127.0.0.1:3306/%s' % (user,password,database)

# Set sqlalchemy to automatically track the database
SQLALCHEMY_TRACK_MODIFICATIONS = True

# The original SQL statement is displayed when querying
app.config['SQLALCHEMY_ECHO'] = True

# Prohibit automatic submission of data processing
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False

# Read configuration
app.config.from_object(Config)

# Create database sqlalchemy tool object
db = SQLAlchemy(app)

class Role(db.Model):
# Define table name
__tablename__ = 'roles'
# Define field
id = db.Column(db.Integer, primary_key=True,autoincrement=True)
name = db.Column(db.String(64), unique=True)
users = db.relationship('User',backref='role') # Reverses multiple User model objects associated with role s

class User(db.Model):
# Define table name
__tablename__ = 'users'
# Define field
id = db.Column(db.Integer, primary_key=True,autoincrement=True)
name = db.Column(db.String(64), unique=True, index=True)
email = db.Column(db.String(64),unique=True)
pswd = db.Column(db.String(64))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id')) # Set foreign keys

if __name__ == '__main__':

# Delete all tables
db.drop_all()

# Create all tables
db.create_all()
  1. Execute the script and create the database
python3 15_SQLAlchemy.py

3. View the created table structure in mysql

mysql> show tables;
+--------------------+
| Tables_in_flask_ex |
+--------------------+
| roles |
| users |
+--------------------+
2 rows in set (0.00 sec)

mysql>
mysql> desc users;
+---------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | YES | UNI | NULL | |
| email | varchar(64) | YES | UNI | NULL | |
| pswd | varchar(64) | YES | | NULL | |
| role_id | int(11) | YES | MUL | NULL | |
+---------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

mysql>
mysql> desc roles;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(64) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql>

After creating the data table, let's see how to add, delete, query and modify the data.

Common SQLAlchemy query filters

filterexplain
filter()Add the filter to the original query and return a new query
filter_by()Add the equivalent filter to the original query and return a new query
limitUse the specified value to limit the results returned by the original query
offset()Offset the result returned by the original query and return a new query
order_by()Sort the original query results according to the specified criteria and return a new query
group_by()Group the original query results according to the specified criteria and return a new query

Common SQLAlchemy query executors

methodexplain
all()Returns all the results of the query as a list
first()Returns the first result of the query. If it is not found, it returns None
first_or_404()Returns the first result of the query. If it is not found, it returns 404
get()Returns the row corresponding to the specified primary key. If it does not exist, returns None
get_or_404()Returns the row corresponding to the specified primary key. If it does not exist, it returns 404
count()Number of returned query results
paginate()Returns a Paginate object that contains the results within the specified range

Create table:

db.create_all()

Delete table

db.drop_all()

Insert a single piece of data at a time

if __name__ == '__main__':

# Insert a role data
role1 = Role(name='admin')
db.session.add(role1)
db.session.commit()

# Insert another piece of data
role2 = Role(name='user')
db.session.add(role2)
db.session.commit()

Execute script:

python3 15_SQLAlchemy.py

View the inserted data in mysql as follows:

mysql> select * from roles \G
*************************** 1. row ***************************
id: 1
name: admin
*************************** 2. row ***************************
id: 2
name: user
2 rows in set (0.00 sec)

Insert multiple pieces of data at one time

# Insert multiple pieces of data at one time
user1 = User(name='wang',email='wang@163.com',pswd='123456',role_id=role1.id)
user2 = User(name='zhang',email='zhang@189.com',pswd='201512',role_id=role2.id)
user3 = User(name='chen',email='chen@126.com',pswd='987654',role_id=role2.id)
user4 = User(name='zhou',email='zhou@163.com',pswd='456789',role_id=role1.id)
db.session.add_all([user1,user2,user3,user4])
db.session.commit()

Insert data as follows:

python3 15_SQLAlchemy.py

Query the inserted data in mysql as follows:

mysql> select * from users \G
*************************** 1. row ***************************
id: 1
name: wang
email: wang@163.com
pswd: 123456
role_id: 1
*************************** 2. row ***************************
id: 2
name: zhang
email: zhang@189.com
pswd: 201512
role_id: 2
*************************** 3. row ***************************
id: 3
name: chen
email: chen@126.com
pswd: 987654
role_id: 2
*************************** 4. row ***************************
id: 4
name: zhou
email: zhou@163.com
pswd: 456789
role_id: 1
4 rows in set (0.00 sec)

mysql>

Although it seems that multiple pieces of data are inserted at one time in python, in fact, multiple line insertion statements are also executed in mysql. You can see the following from the mysql log:

2019-11-23T16:48:56.984459Z 9061 Query INSERT INTO users (name, email, pswd, role_id) VALUES ('wang', 'wang@163.com', '123456', 1)
2019-11-23T16:48:56.997132Z 9061 Query INSERT INTO users (name, email, pswd, role_id) VALUES ('zhang', 'zhang@189.com', '201512', 2)
2019-11-23T16:48:57.010175Z 9061 Query INSERT INTO users (name, email, pswd, role_id) VALUES ('chen', 'chen@126.com', '987654', 2)
2019-11-23T16:48:57.024134Z 9061 Query INSERT INTO users (name, email, pswd, role_id) VALUES ('zhou', 'zhou@163.com', '456789', 1)

In fact, multiple values are not merged into one insert statement, and multiple insert statements are still inserted one by one.

Query: filter_by exact query

Returns all user s whose name is equal to wang

User.query.filter_by(name='wang').all()

In the interaction model, execute the following:

>python3 db_demo.py shell
In [1]: from db_demo import User

In [2]: User.query.filter_by(name='wang').all()
Out[2]: [<User 1>]

In [3]:

first() returns the first object queried

User.query.first()

The implementation is as follows:

In [3]: User.query.first()
Out[3]: <User 1>

all() returns all the queried objects

User.query.all()

The implementation is as follows:

In [4]: User.query.all()
Out[4]: [<User 1>, <User 2>, <User 3>, <User 4>]

In [5]:

filter fuzzy query, which returns all data with g at the end of the name.

User.query.filter(User.name.endswith('g')).all()

The implementation is as follows:

In [5]: User.query.filter(User.name.endswith('g')).all()
Out[5]: [<User 1>, <User 2>]

get(), the parameter is the primary key. If the primary key does not exist, no content is returned

User.query.get()

The implementation is as follows:

In [6]: User.query.get(2)
Out[6]: <User 2>

In [7]: user2 = User.query.get(2)

In [8]: user2.name
Out[8]: 'zhang'

Logical non, return all data whose name is not equal to wang.

User.query.filter(User.name!='wang').all()

The implementation is as follows:

In [9]: User.query.filter(User.name!='wang').all()
Out[9]: [<User 2>, <User 3>, <User 4>]

Logical and, and * needs to be imported, and all data satisfying the and * () condition is returned.

from sqlalchemy import and_
User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()

The implementation is as follows:

In [10]: from sqlalchemy import and_

In [15]: users = User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()

In [16]: for user in users:
...: print(user.email)
...:
zhou@163.com

Logical or, or needs to be imported_

from sqlalchemy import or_
User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()

The implementation is as follows:

In [17]: from sqlalchemy import or_

In [18]: users = User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()

In [19]: for user in users:
...: print(user.name, user.email)
...:
wang wang@163.com
zhang zhang@189.com
chen chen@126.com
zhou zhou@163.com

In [20]:

not_ Equivalent to negation

from sqlalchemy import not_
User.query.filter(not_(User.name=='chen')).all()

The implementation is as follows:

In [22]: from sqlalchemy import not_

In [25]: users = User.query.filter(not_(User.name=='chen')).all()

In [26]: for user in users:
...: print(user.name, user.email)
...:
wang wang@163.com
zhang zhang@189.com
zhou zhou@163.com

Delete after querying data

user = User.query.first()
db.session.delete(user)
db.session.commit()
User.query.all()

The implementation is as follows:

(venv) $ >python3 db_demo.py shell

In [1]: from db_demo import User

In [3]: user = User.query.first()

In [5]: from db_demo import db

In [6]: db.session.delete(user)

In [7]: db.session.commit()

In [8]: User.query.all()
Out[8]: [<User 2>, <User 3>, <User 4>]

Update data

user = User.query.first()
user.name = 'dong'
db.session.commit()
User.query.first()

The implementation is as follows:

In [1]: from db_demo import User

In [5]: from db_demo import db

In [9]: user = User.query.first()

In [10]: user
Out[10]: <User 2>

In [11]: user.name
Out[11]: 'zhang'

In [12]: user.name = 'dong'

In [13]: db.session.commit()

In [14]: user = User.query.first()

In [15]: user.name
Out[15]: 'dong'

Using update

User.query.filter_by(name='zhang').update({'name':'li'})

The implementation is as follows:

In [21]: User.query.filter_by(name='dong').update({'name':'li'})
Out[21]: 0

In [22]: User.query.get(2)
Out[22]: <User 2>

In [23]: user = User.query.get(2)

In [24]: user.name
Out[24]: 'li'

Example of association query: the relationship between roles and users is a one to many relationship. A role can have multiple users, and a user can only belong to one role.

All users associated with the query role:

#Query the roles whose table id is 1
role1 = Role.query.get(1)
#Query all users in this role
role1.users

The implementation is as follows:

In [25]: from db_demo import Role

In [26]: role1 = Role.query.get(1)

In [27]: role1.users
Out[27]: [<User 4>]

In [28]: role2 = Role.query.get(2)

In [29]: role2.users
Out[29]: [<User 2>, <User 3>]

Role of association query user:

#Query the users with id 3 in the users table
user1 = User.query.get(3)
#Query the user's role
user1.role

The implementation is as follows:

In [30]: user1 = User.query.get(3)

In [31]: user1.role
Out[31]: <Role 2>