python链接mysql系统结构设计_MySQLpython交互
MySQL&python交互
一、Python操作MySQL步驟(原始的執行SQL語句)
引入pymysql模塊
image.png
from pymysql import *
Connection對象
用于建立與數據庫的連接
創建對象:調用connect()方法
conn = connect(
host='localhost', port=3306,user='root',password='mysql',database='jing_dong', charset='utf8')
# host: 連接mysql主機IP地址
# port: 連接的mysql主機的端口,默認是3306
# database: 數據庫的名稱
# user: 連接的用戶名
# password: 連接密碼
# charset: 通信的編碼方式
對象的方法
conn.close() # 關閉連接
conn.commit() # 提交
conn.cursor() # 返回cursor對象,用于執行sql語句并獲取結果
Cursor對象
用于執行SQL語句,使用頻度最高的語句為select、insert、update、delete
獲取Cursor對象:調用Connection對象的cursor()方法
cs1 = conn.cursor()
# 執行sql語句
rows = cs1.execute("""select * from goods;""")
print(rows) # rows:影響的數據庫行數
對象的方法
cs1.close() # 關閉數據庫的查詢連接
cs1.execute() # 執行sql語句,返回受影響的行數
cs1.fetchone() # 執行查詢語句時,獲取查詢結果集的第一個行數據,返回一個元祖
cs1.fetchall() # 執行查詢時,獲取查詢結果集的所有行,一行構成一個元祖,在將這些元祖祖入一個元祖返回
對象的屬性
cs1.rowcount # 只讀屬性,表示最近一次execute()執行后受影響的行數
cs1.connection # 獲得當前連接對象
二、Mysql與Flask的交互
Flask提供了擴展Flask-SQLAlchemy,對其交互,操作數據庫,是一個簡化SQLALchemy操作的擴展
SQLALchemy 實際是對數據庫的抽象,不使用SQL語句,通過Python對象來操作數據庫。
SQLALchemy 是一個關系型數據庫框架,提供了高層的ORM和底層的原生數據庫的操作。
安裝
pip install flask-sqlalchemy
# 如果連接的是mysql數據庫,需要安裝mysqldb
pip insstall flask-mysqldb
數據庫連接設置
在Flask-SQLAlchemy中,數據庫使用URL指定,而且程序使用的數據庫必須保存到flask配置對象的SQLALCHEMY_DATABASE_URI鍵中。
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test'
# 動態追蹤修改設置,如未設置只會提示警告,默認是True/設置為False
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
#查詢時會顯示原始SQL語句
app.config['SQLALCHEMY_ECHO'] = True
# 文檔:http://docs.sqlalchemy.org/en/latest/core/engines.html
db = SQLAlchemy(app) # 要把 app 對象注冊到SQLAlchemy中
常用的SQLALchemy字段類型
Integer int 普通整數
String str 變長字符串
Text str 變長字符串,對較長或不限長的字符串做了優化
Boolean bool 布爾值
Date datetime.date 時間
Time datetime.datetime 日期和時間
常用的SQLAlchemy列選項
是對列的約束,字段約束
選項名
說明
primary_key
如果為True,代表表的主鍵
unique
如果為True,代表這列不允許出現重復的值
index
如果為True,為這列創建索引,提高查詢效率
nullable
如果為True,允許有空值,如果為False,不允許有空值
default
為這列定義默認值
常用的SQLALchemy關系選項
backref
在關系的另一模型中添加反向引用
primary join
明確指定兩個模型之間使用的聯結條件
uselist
如果為False,不使用列表,而使用標量值
order_by
指定關系中記錄的排序方式
secondary
指定多對多關系中關系表的名字
secondary join
在SQLAlchemy中無法自行決定時,指定多對多關系中的二級聯結條件
1. 基本演練代碼
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 鏈接數據庫(數據庫地址)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/flask01'
# 自動追蹤數據庫的修改
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 查詢時會顯示原始SQL語句
# app.config['SQLALCHEMY_ECHO'] = True
# 先給flask對象設置配置,在傳對象數據庫--創建SQLAlchemy傳入app:目的:獲取數據庫相關參數
db = SQLAlchemy(app)
class Role(db.Model):
# 定義表名
__tablename__ = 'roles'
# 定義列對象
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
us = db.relationship('User', backref='role')
# repr()方法顯示一個可讀字符串
# 直接對象回車就可以打印返回的數據 __str__的區別print打印實例對象
def __repr__(self):
return 'Role:name-%s,id-%s' % (self.name, self.id)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True, index=True)
email = db.Column(db.String(64), unique=True)
password = db.Column(db.String(64))
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __repr__(self):
return 'User:name-%s,id-%s' % (self.name, self.id)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
# 這兩個僅供測試使用,開發上線不能使用
# 刪除所有表的數據
db.drop_all()
# 創建新表
db.create_all()
# 添加角色數據
ro1 = Role(name='admin')
db.session.add(ro1)
db.session.commit()
# 再次插入一條數據
ro2 = Role(name='user')
db.session.add(ro2)
db.session.commit()
# 一次性插入十條數據
us1 = User(name='wang', email='wang@163.com', password='123456', role_id=ro1.id)
us2 = User(name='zhang', email='zhang@189.com', password='201512', role_id=ro2.id)
us3 = User(name='chen', email='chen@126.com', password='987654', role_id=ro2.id)
us4 = User(name='zhou', email='zhou@163.com', password='456789', role_id=ro1.id)
us5 = User(name='tang', email='tang@itheima.com', password='158104', role_id=ro2.id)
us6 = User(name='wu', email='wu@gmail.com', password='5623514', role_id=ro2.id)
us7 = User(name='qian', email='qian@gmail.com', password='1543567', role_id=ro1.id)
us8 = User(name='liu', email='liu@itheima.com', password='867322', role_id=ro1.id)
us9 = User(name='li', email='li@163.com', password='4526342', role_id=ro2.id)
us10 = User(name='sun', email='sun@163.com', password='235523', role_id=ro2.id)
db.session.add_all([us1, us2, us3, us4, us5, us6, us7, us8, us9, us10])
db.session.commit()
app.run(debug=True)
2.在ipython環境下測試
flask_sqlalchemy中,修改數據庫
會話管理用db.session表示。在數據寫入數據庫前,要將數據添加到會話中,在調用commit()方法提交會話
查詢操作是通過query 對象操作數據
增-刪-改都需要commit
一、增
In [1]: from day04 import *
In [2]: role = Role(name='admin01')
In [3]: db.session.add(role)
In [4]: db.session.commit()
二、改
In [5]: role.name = 'admin001'
In [6]: db.session.commit()
三、刪
In [7]: db.session.delete(role)
In [8]: db.session.commit()
————————————查詢------------------------------------------------------------
查看用戶對應的角色
from database import *
user查詢出來是模型的對象,查詢具體的值的時候,使用對象的屬性查詢屬性值
創建出來的每一個模型對象,就是一條數據,數據模型類定義的屬性就是模型的字段屬性數據
user = User.query.get(1)
user.role.name
user:模型實例對象 role:反向引用的字段屬性 name:查詢的字段屬性
查看管理角色有那些用戶
role = Role.query.get(1)
In [7]: role
Out[7]:
In [8]: role.users # 生成對象,在點屬性查詢結果值
Out[8]: [, ]
In [10]: role.users[1].name
Out[10]: '王五'
增加數據
role = Role(name='admin01')
In [3]: db.session.add(role)
In [4]: db.session.commit()
修改數據
In [3]: role.name='admin01'
In [4]: db.session.commit()
刪除數據
In [7]: db.session.delete(role)
In [8]: db.session.commit()
----------------------------------------查詢需求----------------------------------------------
1.查詢所有用戶數據
因為repr可以直接使用對象(User)來查詢便于查詢
User.query.all()
2.查詢有多少個用戶
User.query.count()
3.查詢第1個用戶
User.query.first()
4.查詢id為4的用戶[3種方式]
User.query.get(4)
過濾器是做數據檢索判斷,后面要加上執行器
filter的功能比較強大,filter_by的查詢功能簡單
User.query.filter(User.id==4).all()
User.query.filter_by(id=4).first()
filter的語法格式:
filter_by(屬性名=X)
filter(模型名.屬性名==X)
5.查詢名字結尾字符為g的所有數據[開始/包含]
User.query.filter(User.name.endswith('g')).all() -- 以什么結尾
User.query.filter(User.name.startswith('g')).all() --以什么開始
User.query.filter(User.name.contains('g')).all() --包含
6.查詢名字不等于wang的所有數據[2種方式]
6.1 User.query.filter(User.name!='wang').all()
6.2 (不用)
from sqlalchemy import not_
User.query.filter(not_(User.name=='wang')).all()
7.查詢名字和郵箱都以 li 開頭的所有數據[2種方式]
7.1 User.query.filter(User.name.startswith('li'),User.email.startswith('li')).all()
7.2
8.查詢password是 123456 或者 email 以 itheima.com 結尾的所有數據
from sqlalchemy import or_
User.query.filter(or_(User.password=='123456',User.email.endswith('itheima.com'))).all()
9.查詢id為 [1, 3, 5, 7, 9] 的用戶列表
User.query.filter(User.id.in_([1, 3, 5, 7, 9])).all()
10.查詢name為liu的角色數據
In [16]: user = User.query.filter(User.name=='liu').first()
In [17]: user
Out[17]: User:name-liu,id-8
In [18]: user.role.name
Out[18]: 'admin'
11.查詢所有用戶數據,并以郵箱排序
User.query.order_by('email').all()
12.每頁3個,查詢第2頁的數據
返回一個Paginate對象,它包含指定范圍內的結果
paginate = User.query.paginate(2, 3, False)
In [33]: paginate
Out[33]:
In [34]: paginate.items # 獲取分頁的數據
Out[34]: [User: name-zhou id-4, User: name-tang id-5, User: name-wu id-6]
In [35]: paginate.page # 當前頁碼
Out[35]: 2
In [36]: paginate.pages # 總頁碼
Out[36]: 4
3. 數據庫遷移
在Flask中可以使用Flask-Migrate擴展,來實現數據遷移。并且集成到Flask-Script中,所有操作通過命令就能完成
為了導出數據庫遷移命令,Flask-Migrate提供了一個MigrateCommand類,可以附加到flask-script的manager對象上。
pip install flask-migrate
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate,MigrateCommand
from flask_script import Shell,Manager
....
db = SQLAlchemy(app)
#第一個參數是Flask的實例,第二個參數是Sqlalchemy數據庫實例
migrate = Migrate(app,db)
#manager是Flask-Script的實例,這條語句在flask-Script中添加一個db命令
manager.add_command('db',MigrateCommand)
.....
創建遷移腳本
pyhton database.py db init
python database.py db migrate -m 'initial migration'
python database.py db upgrade
三、Mysql與Django的交互
Django默認初始配置使用sqlite數據庫。使用MySQL數據庫首先需要安裝驅動程序。
在Django的工程同名子目錄的init.py文件中添加執行MySQL的執行驅動。
在setting文件中配置DATABASES配置信息
pip install Pymysql
# 在__init__文件下
from pymysql import install_as_MySQLdb
install_as_MySQLdb()
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1', # 數據庫主機
'PORT': 3306, # 數據庫端口
'USER': 'root', # 數據庫用戶名
'PASSWORD': 'mysql', # 數據庫用戶密碼
'NAME': 'django_demo' # 數據庫名字
}
}
四、MySQL的SQL語句
基本查詢
select id as 序號, name as 名字,gender as 性別 from students;# 給查詢字段起別名
select s.id,s.name,s.gender from students as s; # 給表起別名
消除重復行
在 select 后面,列的前面使用 distinct
select distinct 列1,.... from 表名;
select distinct gender from students;
條件查詢
使用 where子句對表中的數據塞選,結果為true的行會出現在結果集
seclect * from 表名 where 條件
where子句后面支持多種運算符,進行條件的處理
1. 比較運算符 # =、>、>=、<、<=、!=、
select * from students where age != 18;
2. 邏輯運算符 # and、or、not
select * from students where not( age > 18 and gender = "女");
3. 模糊查詢 # like、% 表示任意多個字符、__ 表示一個任意字符
select * from students where name like '黃%' or name like '%靖';
4. 范圍查詢 # in 表示在一個非連續的范圍、between...and ...表示在一個連續的范圍內
select * from students where age not between 18 and 34;
5. 空判斷 # is null:判空、is not null:判非空
select * from students where height is not null and gender=1;
排序
為了方便查看數據,可以對數據進行排序
select * from 表名 order by 列1 asc|desc, [列2 asc|desc,...]
# asc:升序;desc:降序
select * from students where (age between 18 and 34) and gender = "女" order by height desc,age asc,id desc;
聚合函數
為了快速統計
1. count(*):表示計算總行數,括號中寫星與列名,結果是相同的 select count(*) from students;
2. max(列):表示求此列的最大值 select max(id) from students where gender=2;
3. min(列):表示求此列的最小值 select min(id) from students where is_delete=0;
4. sum(列):表示求此列的和 select sum(age) from students where gender=1;
5. avg(列):表示求此列的平均值 select avg(id) from students where is_delete=0 and gender=2;
分組
group by:將查詢結果按照1個或多個字段進行分組,字段值相同為一組
group by可用于單個字段、多個字段分組 。一般都是和其他函數一起使用
select 分組字段 from 表名 group by 分組字段;
select gender,count(*) from students group by gender;
group by + group_concat()
# group_concat(字段名):可以作為一個輸出字段來使用
# 表示分組之后,根據分組結果,使用group_concat()來放置每一組的某個字段的值集合
select gender,group_concat(name) from students group by gender;
group by + 集合函數
# 通過group_concat(),可以對統計出來每個分組的某個字段值的集合。通過聚合函數來對 值的集合 操作
select gender,count(*) from students group by gender;
group by + having
having:條件表達式:原來分組查詢后指定一些條件輸出查詢的結果
having 作用和where一樣:但是having只能用在group by
having 后通常也要跟 聚合函數
select gender,avg(age),group_concat(name) from students group by gender having avg(age) > 30; # 查詢性別分組、分組集合字段有哪些name、對于輸出結果判斷是否符合 平均年齡大于30
group by + with rollup
with rollup:在最后新增一行,來記錄當前列里面所有記錄的總和 (匯總的作用)
select gender,group_concat(age) from students group by gender with rollup;
獲取部分行
當數據量較大時,在一頁查看數據limit要放到最后
起始位置 = (頁面數-1)每一頁的個數*
select * from students where is_delete=0 limit (n-1)*m,m
# start:開始的地方,獲取count條數據
select * from 表名 limit start,count
select * from students limit 6,2; # 每頁顯示2個,第4個頁面
select * from students order by age asc limit 10,2 ; # 每頁顯示2個,第6個頁面,按照年齡排序
連接查詢
mysql支持三種類型的連接查詢:
內連接查詢:查詢結果為兩個表的匹配的結果(交集)
右連接查詢:查詢結果為兩個表的匹配的數據,右表特有的數據,對于左表不存在數據使用null填充
左連接查詢:查詢的結果為兩個表匹配到的數據,左表特有的數據,對于右表中不存在的數據使用null填充
# inner join ... on :on 后面是兩個表之間的查詢條件
selcet * from 表1 inner或left或right jion 表2 on 表1.列 = 表2.列
# 查詢學生姓名和班級姓名
select s.name,c.name from student as s inner join classes as c on s.cls_id = c.id
自關聯
類似省市區-三級聯動的表格設計
# 1.查詢所有的省份
select * from areas where pid is null;
# 2.查詢某個省份下的所有城市
select pid from areas where atitle = "河南省"
select * from areas where pid=(select pid from areas where atitle = "河南省")
或者:
select * from areas as a1 inner join areas as a2 on a1.pid=a2.aid where a2.title=".."
子查詢
in 范圍
主查詢 where 條件 in (列子查詢)
# 1.標量 子查詢
select * from students where age > (select avg(age) from students);
# 2.列級 子查詢
select name from classes where id in (select cls_id from students);
# 3.行級 子查詢
select * from students where (height,age) = (select max(height),max(age) from students);
增加數據
添加數據
格式:insert into 表名(字段...) values(值1...)
insert into students(name,age) values('zhang', '18') # 部分插入數據
insert into students(name) values('李四'),('王五'); # 多行插入數據
修改數據
格式:
update 表名 set 字段 = 值,字段2 = 值2 where 條件;
update user set name='小名'; # 全部修改
update user set name='小明' where id=2; # 條件修改
update students set gender='男',name='小哈' where id=10; # 條件修改多個值
五、MySQL的高級使用
1. 視圖
視圖就是一條select語句執行的結果;作用:就是便于查詢
視圖是對若干張基本表的引用,一張虛表,查詢語句執行的結果(基本表結構發生改變,視圖也會改變)
定義視圖
# 創建視圖
create view 視圖名稱 as select語句; # 視圖名稱建議使用 v_開頭
# 查看視圖
show tables;
# 刪除視圖
drop view 視圖名稱;
2. 事務命令
注意:修改數據的命令會自動的觸發事務,包括insert、update、delete。
手動開啟事務原因:可以多次數據修改,要么一起成功,要么一起回滾之前的數據。
# 1. 開啟事務
begin;
# 2. 提交事務
commit;
# 3. 回滾
rollback;
2、直接用 SET 來改變 MySQL 的自動 交模式:
SET AUTOCOMMIT=0 禁止自動 交
SET AUTOCOMMIT=1 開啟自動 交
3. 索引
一種特殊的文件(InnoDB數據表上的索引,是表空間的一個組成部分),包含對數據表里面所有記錄的引用指針。好比一本書的目錄,快速的查詢。
在表格上創建唯一的索引。意味著兩個行不能擁有相同的索引值。
索引原理
索引問題就是一個查找問題。
數據庫索引,是數據庫管理系統中一個排序的數據結構,以協助快速查詢、更新數據庫表中數據。索引的實現通常使用 B 樹及其變種 B+樹。 在數據之外,數據庫系統還維護著滿足特定查找算法的數據結構,這些數據 結構以某種方式引用(指向)數據,這樣就可以在這些數據結構上實現高級 查找算法。這種數據結構,就是索引。
相當于把數據進行分塊整理,從小塊中查詢數據。
索引使用
注意:
建立太多索引將會影響更新和插入速度,索引會占用磁盤空間
# 1.創建索引
create index 索引名稱 on 表名(字段名稱(長度)); # 如果字段是字符串,需要指定長度。與定義時一樣
# 2.查看索引
show index from 表名;
# 3.刪除索引
drop index 索引名稱 on 表名;
# 查詢開啟運行時間監測
set profiling = 1;
# 查看執行的時間 show profiles;
總結
以上是生活随笔為你收集整理的python链接mysql系统结构设计_MySQLpython交互的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编程软件有哪些(c语言编程软件有哪些)
- 下一篇: linux 删除mysql_MySQL—