参考文档: 更多mysql,请参考
数据库介绍
数据库是按照数据结构来阻止、存储和管理数据的仓库。
每个数据库都有一个或多个不同的API用于创建、访问、管理、搜索和复制所保存的数据。
我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理大数据量。
所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数据概念和方法来处理数据库中的数据。
RDBMS(Relational Database Management System)的特点:
- 数据以表格的形式出现
- 每行为各种记录名称
- 每列为记录名称锁对应的数据域
- 许多的行和列注册一张表单
- 若干的表单注册database
关系型数据库包括:Oracle, Mysql,SQLServer,DB2,Postgresql,Sqlite,acess等
Mysql数据库
Mysql是最流行的关系型数据库管理系统,在web应用方面mysql是最好的
linux安装:rpm -i MySQL -5.0.9-0.i386.rpm
管理Mysql的命令
use 数据库名:选择要操作的mysql数据库,使用该命令后素有mysql命令都只针对该数据库
show databases:列出mysql数据库管理系统的数据库列表
show tables :显示指定数据库的所有表,使用改名了前需要用use命令选择要操作的数据库。
show columns from 数据表:显示数据表的属性,属性类型,主键信息,是否为NULL,默认值等其他信息create database testdb charset "utf8";创建一个叫testdb的数据库,并且让其支持中文
drop database testdb;删除数据库
show index from 数据表:显示数据表的详细索引信息,包括primary key(主键)。
mysql数据类型
mysql中定义数据 字段的累心归队你数据库的优化是非常重要的。
mysql支持多种类型,大致可以分为三类:数值、日期/时间和字符串类型。
数值类型
mysql支持所有标准sql数值数据类型。
这些类型包括龑哥数值数据类型(integer,smallint,decimal和numeric),以及近似数值类型(float、real和double precision)。
关键字int是integer的同义词,关键字dec是decimal的同义词。
bat数据类型保存位字段值,兵器支持MyISAM、memory、InNoDB和BDB表。
作为sql标准的扩展,mysql也支持整数类型tinyint、mediumint和bigint。
日期/时间类型
表示时间值的日期和时间类型为datetime、date、timestamp、time、year
每个时间类型都有一个有效值范围和一个‘零’值,当指定不合法的mysql不能表示的值时使用‘零’值。
timestame类型有转悠的自动更新特性
字符串类型
字符串类型只char,varchar,binary,varbinary,blob,text,enum和set
mysql的常用命令
mysql创建数据表:
用test数据 ,创建一个表叫student,包含stu_id(int类型,不能为空,自动递增) , name(字符类型,不能为空), age(int类型,不能为空), register_date(date格式)
#create table table_name(column_name column_type)use test;#使用test数据库create table student(stu_id int not null auto_increment,name char(32) not null,#字符类型,不能为空age int not null,#int类型,不能为空register_date date,#register_date(date格式)primary key(stu_id))#设置主键为stu_id
插入数据:
语法: insert into table_name(field1,field2,...fieldN) values (value1,value2,...valueN)insert into student(name,age,register_date) values("alex li",22,"2018-04-17")
查询数据语法:
- select column_name,column_name from table_name [where Clause] [offset m][limit n]
- 查询语句中你可以使用一个或者多个表,表之间使用逗号(,)分隔,并使用where语句来设定插叙条件。
- select命令可以读取一条或者多条纪录。
- 你可以使用星号(*)来代替其他字段,select语句会返回表的所有字段数据。
- 你可以通过offset指定select语句开始插叙的数据偏移量。默认情况下偏移量为0.
- 你可以使用limit属性来设定返回的纪录数
比如这个SQL ,limit后面跟的是3条数据,offset后面是从第3条开始读取
select * from student limit 3 offset 2;
而这个SQL,limit后面是从第3条开始读,读取1条信息。
select * from student limit 3 ,1;
where 子句
语法:select field1,field2,...fieldN from table_name1,table_name2...[where condition1 [and [or]] condition2....]
select * from student where register_date > '2016-03-04'
update 更新语法
UPupdate table_name set fiele1 = new-value1,field2 = new-value2 [where Clause]
upupdate student set age 23 ,name = "Alex Li" where stu_id = 1;
DELETE 语句语法:
delete from table_name [where Clause]
delete from student where stu_id = 5;
MySQL LIKE 子句语法:
select field1,field2,...fieldN table_name1,table_name2... where field1 like condition1 [and[or] filed2 = "somevalue"]
select * from student where name binary like "%Li";select * from student where name binary like binary "%Li";#只匹配大写
MySQL 排序
SELECT field1, field2,...fieldN table_name1, table_name2... ORDER BY field1, [field2...] [ASC [DESC]]
select *from student where name like binary "%Li" order by stu_id desc;
GROUP BY 语句
SELECT
column_name,
function
(column_name)
FROM
table_name
WHERE
column_name operator value
GROUP
BY
column_name;
with rollup可以计算总数
coalesce 可以将统计的类别改名,null改为自定义的字符
alter命令
我们需要修改数据表名或者修改数据表字段时,就需要使用到alter命令
增加字段:增加性别字段
alter table student add sex enum("M","F");
删除字段:
alter table student drop age;
修改字段:
利用modify修改sex字段为非空
alter table student modify sex enum("F","M") not null;
利用change修改
alter table student change sex gender char(32) not null default "x";
关于外键
外键,一个特殊的索引,用于关键两个表,只能是指定内容
以下两种写法均可
create table study_record (id int(11) not null auto_increment,day int(11) not null,status char(32) not null ,stu_id int(11) NOT NULL,primary key (id),key fk_student_key (stu_id),constraint fk_student_key foreign key (stu_id) references student (stu_id))CREATE TABLE `study_record` ( `id` int(11) NOT NULL auto_increment, `day` int(11) NOT NULL, `status` char(32) NOT NULL, `stu_id` int(11) NOT NULL, primary key (`id`), key `fk_student_key` (`stu_id`), CONSTRAINT `fk_student_key` FOREIGN KEY (`stu_id`) REFERENCES `student` (`stu_id`))
此时,如果student 对应的stu_id 不存在,study_record也无法插入,这叫外键约束
同样道理,如果有student表中跟这个study_record表有关联的数据,你是不能删除student表中与其关联的纪录
mysql null值处理
我们已经知道MySQL使用 SQL SELECT 命令及 WHERE 子句来读取数据表中的数据,但是当提供的查询条件字段为 NULL 时,该命令可能就无法正常工作。
为了处理这种情况,mysql提供了三大运算符:is null:当列的值是null,此运算符返回True。is not null:当列的值部位null,运算符返回True<=>:比较操作符(不同于=运算符),当比较的两个值都未null时返回True。关于null的条件比较运算是比较特殊的,你不能使用=null或!=null在列中查找null值
在mysql中,null值与任何其他值的比较(即使是null)永远返回false,即null = null返回false。
mysql中处理null使用is null 和is not null运算符。mysql连接(left join,right join,inner join,full join)
这里介绍使用join在两个或多个表中查询数据。join按照功能大致分为如下三类:inner join(内连接,或等值连接):获取两个表中字段匹配关系的纪录。left join(左连接):获取左表所有纪录,即使右表没有对应匹配的纪录。right join(右连接):与left join相反,用于获取右表所有纪录,即使左表没有对应匹配的纪录。
insert into A(a)values(1);
insert into A(a)values(2);insert into A(a)values(3);insert into A(a)values(4);insert into B(b)values(3);
insert into B(b)values(4);insert into B(b)values(5);insert into B(b)values(6);inner join:(显示两个表的交集)
select * from A inner join B on A.a = B.b; #(一般写这个) 可以写成: select A.*,B.* from A,B where A.a = B.b;left join:(差集)
select * from A left join B on A.a = B.b;
right join:
select * from A right join B on A.a = B.b;
full join:并集(mysql 不直接支持这个)
select * from A full join B on A.a = B.b;#(mysql 不直接支持这个)
mysql支持的写法:
select * from A left join B on A.a = B.b union select * from A right join B on A.a = B.b;
事务
mysql事务主要用于处理操作量大,复杂度高的数据。比如说,在人员管理系统中,你删除一个人员,你即需要删除人员的基本资料,也要删除和该人员相关的信息,比如信箱、文章等等,这样,这些数据库操作语句就构成了一个事务!
在mysql中只有使用了Innodb数据库引擎的数据库或表才支持事务,mysql默认就使用了这个数据引擎的;事务处理可以用来维护数据库的完整性,包子成批的sql语句要么全部执行,要么全部不执行;事务用来管理insert,update,delete语句;一般来说,事务是必须满足4个条件(ACID):Atomicity(原子性)、Consistency(稳定性)、Isolation(隔离性)、Durability(可靠性)
- 事务的原子性:一组事务,要么成功,要么撤回;
- 稳定性:有非法数据(外键约束之类),事务撤回;
- 隔离性:事务独立运行。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
- 可靠性:软、硬件奔溃后,InNoDB数据表驱动会利用日志文件重构修改。可靠性和高速度不可兼得,innodb_flush_log_at_trx_commit选项决定什么时候把事务保存到日志里。
在mysql控制台使用事务来操作
begin;
insert into student (name,age,register_date) values("dashuaige",18,"2018-04-04");rollback;#回滚,这样数据是不会写入的如果是数据没有问题,就输入commit提交命令就行。索引
mysql索引的建立对于mysql的高效运行是很重要的,索引可以大大提高mysql的检索速度。
索引分单列索引和组合索引。单列索引,即一个索引只包含单个列,一个表可以有多个单列索引,单这不是组合索引。组合索引:即一个索包含多个列。(两个合在一起变成唯一的)创建索引时,你需要确保该索引是应用在sql查询语句的条件(一般作为where子句的条件)。
实际上,索引也是一张表,该表保存了主键和索引字段,并指向实体表的纪录。
缺点:索引会降低更新表的速度,如对表进行insert、update、delete,因为更新表时,mysql不仅仅要保存数据,还要保存一下索引文件,所以速度变慢。同时,还要保存一下索引文件,建立索引占用次品空间的索引文件。
普通索引
主键就是默认索引。
查询索引:show index from student;
创建索引:
语法:create index indexname on mytable (username(length));#length为索引的长度
eg:
create index index_name on student (name(32));
修改表结构
alter mytable add index [indexname] on (username(length))
创建表的时候直接指定
create table mytable(
id int not null,
username varchar(16) not null,
index [indexname] (username(length))
);
删除索引
语法:
drop index [indexname] on mytable;
eg:
drop index index_name on student;
唯一索引
唯一索引:索引列的值必须唯一,但是允许有空值。如果是组合索引,则列值的组合必须唯一。
eg:主键就是唯一索引
创建索引
创建索引
create unique index indexname on mytable(username(length))
修改表结构:
alter mytable add unique [indexname] on (username(length))
创建表的时候直接指定:
create table mytable(\
id int not null,
username varchar(16) not null,
unique [indexname] (username(length))
);
python 操作mysql
参考:点
数据库安装
pip3 install pymysql
使用 pymysql
例子:
import pymysql# 创建连接,相当于建立一个socketconn = pymysql.connect(host = 'localhost',port = 3306,user = 'root',password = 'Choice123',db = 'my_db')# 创建游标,相当于光标,真真正正建立了一个实例cursor = conn.cursor()# 执行SQL,并返回执行行数effect_row = cursor.execute("select * from student")print(effect_row)# 一条条取print(cursor.fetchone())print(cursor.fetchone())print(''.center(60,"="))# 获取前几条数据print(cursor.fetchmany(3))print(''.center(60,"="))# 取全部print(cursor.fetchall())
import pymysql# 创建连接,相当于建立一个socketconn = pymysql.connect(host = 'localhost',port = 3306,user = 'root',password = 'Choice123',db = 'my_db')# 创建游标,相当于光标,真真正正建立了一个实例cursor = conn.cursor()data = [ ("N1","10","2015-05-22"), ("N2", "11", "2015-04-22"), ("N3", "12", "2015-06-22")]cursor.executemany("insert into student (name,age,register_date) VALUES (%s,%s,%s)",data)# 因为默认启动了事务,所以需要commit上去,数据库才有数据conn.commit()# 关闭游标cursor.close()# 关闭连接conn.close()
为了避免写死原生SQL语句,所以介绍ORM
ORM
参考
ORM英文全称object relational mapping,就是对象映射关系程序,简单来说我们类似python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过ORM将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用功能编程语言对数据库进行操作的时候可以直接使用编程语言的对象模型进行操作就可以了,而不用直接使用SQL语言。
ORM的优点:
- 隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他是的我们的通用数据库交互变得简单,并且完全不用考虑该死的SQL语句。
- ORM使我们构造固话数据结构变得简单易行
缺点:
无可避免的,自动化意味着映射何关联管理,代价是牺牲性能。
sqlalchemy
在python中,最有名的ORM框架是SSQLAlchemy。
Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:
MySQL-Python mysql+mysqldb://: @ [: ]/ pymysql mysql+pymysql:// : @ / [? ] MySQL-Connector mysql+mysqlconnector:// : @ [: ]/ cx_Oracle oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...] 更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.html
安装
命令安装:pip3 install sqlalchemy
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,String# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8",echo = True)# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64))# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8",echo = True)# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64))# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()# 生成你要创建的数据对象user_obj = User(name= "alex",password = "alex1234")# 此时还没创建对象,只是类里生成了数据,所以数据库的id是没有的print(user_obj.name,user_obj.password)# 把要创建的数据对象添加到session里,一会会统一创建,这里还是没有创建在数据库里面,所以id也是没有的Session.add(user_obj)# 这里统一提交,在数据库创建数据Session.commit()
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" %(self.id,self.name)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()# # 生成你要创建的数据对象# user_obj = User(name= "alex",password = "alex1234")# # 此时还没创建对象,只是类里生成了数据,所以数据库的id是没有的# print(user_obj.name,user_obj.password)# # 把要创建的数据对象添加到session里,一会会统一创建,这里还是没有创建在数据库里面,所以id也是没有的# Session.add(user_obj)## # 这里统一提交,在数据库创建数据# Session.commit()# 读取单条# data = Session.query(User).filter_by(name="alex").all()# print(data)# print(data[0].name,data[0].password)# 读取多条数据存放到一个列表# data = Session.query(User).filter_by().all()# print(data)# for i in data:# print(data[0].name,data[0].password)# 读取第一条数据# data = Session.query(User).filter_by().first()# print(data)# # 用等号是双等好# data = Session.query(User).filter(User.id==2).all()# print(data)# id大于2的所有数据# data = Session.query(User).filter(User.id>2).all()# print(data)# 多条件,用两个filterdata = Session.query(User).filter(User.id>2).filter(User.id<4).all()print(data)
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" %(self.id,self.name)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()# 多条件,用两个filter# data = Session.query(User).filter(User.id>2).filter(User.id<4).all()#因为这里是生成列表的,所以要用列表的方式显示数据才行data = Session.query(User).filter(User.id>2).filter(User.id<4).first() #这里是取第一个,所以是直接取出数据print(data)data.name = 'Jack Liu'data.password = '123'Session.commit()
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" %(self.id,self.name)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()# 增加一个用户fake_user = User(name='Rain', password='12345')Session.add(fake_user)print(Session.query(User).filter(User.name.in_(['Jack', 'rain'])).all()) # 这时看session里有你刚添加和修改的数据# 回滚了Session.rollback() # 此时你rollback一下# 数据没了,没有加入到数据库print(Session.query(User).filter(User.name.in_(['Jack', 'rain'])).all()) # 再查就发现刚才添加的数据没有了。
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" %(self.id,self.name)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()data = Session.query(User).filter_by().count()print(data)# data2 = Session.query(User).filter(User.name.in_(['alex','alex1234'])).count()data2 = Session.query(User).filter(User.name.in_(['alex'])).count()print(data2)
分组统计需要导入:
from sqlalchemy import func
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" %(self.id,self.name)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()from sqlalchemy import func# func.count(User.name)是统计name的数量print(Session.query(User.name,func.count(User.name)).group_by(User.name).all())# [('alex', 7), ('gui', 1), ('Jack Liu', 1)]
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" %(self.id,self.name)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()data = Session.query(User).filter(User.id == 2).one()print("要删除的数据:",data)Session.delete(data)Session.commit()
连表
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,Stringfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class User(Base): # 表名 __tablename__ = 'user' id = Column(Integer,primary_key=True) name = Column(String(32)) password = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" %(self.id,self.name)class Student(Base): __tablename__ = 'student' stu_id = Column(Integer,primary_key=True) name = Column(String(32)) age = Column(Integer) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" % (self.stu_id, self.name)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()print(Session.query(User).filter(User.id == Student.stu_id).all())
关联外键
先删除原来的数据库以免原来的数据影响
drop database my_db;
创建新的数据库,编码为utf8
create database my_db character set utf8;
之后就能执行下面代码
import sqlalchemyfrom sqlalchemy import create_enginefrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import Column,Integer,String,DATE,ForeignKeyfrom sqlalchemy.orm import sessionmaker# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class Student(Base): __tablename__ = 'student' stu_id = Column(Integer,primary_key=True) name = Column(String(32),nullable=False) age = Column(Integer) register_date = Column(DATE,nullable=False) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s name:%s>" % (self.stu_id, self.name)class StudyRecord(Base): # 表名 __tablename__ = 'study_record' id = Column(Integer, primary_key=True) day = Column(Integer, nullable=False) status = Column(String(32), nullable=False) # 建立外键关系 stu_id = Column(Integer, ForeignKey('student.stu_id')) # 通过这个函数,就能将搜索出来的数据分出来:[<1 name:alex>, <2 name:alex>, <3 name:alex>, <4 name:alex>, <5 name:alex>, <6 name:alex>, <7 name:alex>, <8 name:alex>] def __repr__(self): return "<%s day:%s>" % (self.id, self.day)# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=engine)#生成session实例,这里相当于cursorSession = Session_class()s1 = Student(name = "Alex",register_date = "2014-05-21")s2 = Student(name = "Jack",register_date = "2014-03-21")s3 = Student(name = "Rain",register_date = "2014-04-21")s4 = Student(name = "Eric",register_date = "2013-01-21")study_r1 = StudyRecord(day = 1,status = "Yes",stu_id = 1)study_r2 = StudyRecord(day = 2,status = "NO",stu_id = 1)study_r3 = StudyRecord(day = 3,status = "Yes",stu_id = 1)study_r4 = StudyRecord(day = 1,status = "Yes",stu_id = 2)# 统一增加Session.add_all([s1,s2,s3,s4,study_r1,study_r2,study_r3,study_r4])# 统一提交Session.commit()
多外键关联
from sqlalchemy import Integer,ForeignKey,String,Columnfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import relationshipfrom sqlalchemy import create_engine# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 生成ORM基类Base = declarative_base()class Address(Base): __tablename__ = "address" id = Column(Integer,primary_key=True) street = Column(String(64)) city = Column(String(64)) state = Column(String(64)) # 通过这个函数,就能将搜索出来的数据分出来:Alex转换为:Alex tiantongyuan wudaokou def __repr__(self): return self.streetclass Customer(Base): __tablename__ = "customer" id = Column(Integer,primary_key=True) name = Column(String(64)) # 账单地址以及送货地址都关联了地址 billing_address_id = Column(Integer,ForeignKey("address.id")) shipping_address_id = Column(Integer,ForeignKey("address.id")) # 可以通过billing_address以及shipping_address查询Address类的信息,内容放在内存 billing_address = relationship("Address",foreign_keys = [billing_address_id]) shipping_address = relationship("Address",foreign_keys = [shipping_address_id])# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)
import orm_many_fkfrom sqlalchemy.orm import sessionmaker# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=orm_many_fk.engine)#生成session实例,这里相当于cursorsession = Session_class()# 第一次需要这段代码创建数据# addr1 = orm_many_fk.Address(street = "tiantongyuan",city = "ChangPing",state = "BJ")# addr2 = orm_many_fk.Address(street = "wudaokou",city = "Haidian",state = "BJ")# addr3 = orm_many_fk.Address(street = "Yanjiao",city = "LangFang",state = "HB")## session.add_all([addr1,addr2,addr3])# c1 = orm_many_fk.Customer(name = "Alex",billing_address = addr1,shipping_address = addr2)# c2 = orm_many_fk.Customer(name = "Jack",billing_address = addr3,shipping_address = addr3)## session.add_all([c1,c2])# session.commit()obj = session.query(orm_many_fk.Customer).filter(orm_many_fk.Customer.name == "alex").first()print(obj.name,obj.billing_address,obj.shipping_address)
多对多关联
#一本书可以有多个作者,一个作者又可以出版多本书from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKeyfrom sqlalchemy.orm import relationshipfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerBase = declarative_base()# 第三张表用这个创建,因为这个表不需要用ORM更新book_m2m_author = Table('book_m2m_author', Base.metadata, Column('book_id',Integer,ForeignKey('books.id')), Column('author_id',Integer,ForeignKey('authors.id')), )# 这种方式创建class Book(Base): __tablename__ = 'books' id = Column(Integer,primary_key=True) name = Column(String(64)) pub_date = Column(DATE) # # authors关联第三张表,不是真实的字段,通过secondary查询第三张表数据,Author通过backrep决定books反过来查询这张表Book authors = relationship('Author',secondary=book_m2m_author,backref='books') def __repr__(self): return self.nameclass Author(Base): __tablename__ = 'authors' id = Column(Integer, primary_key=True) name = Column(String(32)) def __repr__(self): return self.name# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db",encoding = "utf-8")# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)
import orm_m2mfrom sqlalchemy.orm import sessionmaker# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=orm_m2m.engine)#生成session实例,这里相当于cursorsession = Session_class()# 第一次需要这段代码创建数据b1 = orm_m2m.Book(name = "learn python with Alex",pub_date = "2015-05-05")b2 = orm_m2m.Book(name = "learn Zhangbility with Alex",pub_date = "2015-09-05")b3 = orm_m2m.Book(name = "learn hook up girls with Alex",pub_date = "2014-10-05")a1 = orm_m2m.Author(name = "Alex")a2 = orm_m2m.Author(name = "Jack")a3 = orm_m2m.Author(name = "Rain")# 建立第三张表的关联关系b1.authors = [a1,a3]b3.authors = [a1,a2,a3]session.add_all([b1,b2,b3,a1,a2,a3])session.commit()# obj = session.query(orm_m2m.Customer).filter(orm_m2m.Customer.name == "alex").first()# print(obj.name,obj.billing_address,obj.shipping_address)
import orm_m2mfrom sqlalchemy.orm import sessionmaker# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=orm_m2m.engine)#生成session实例,这里相当于cursorsession = Session_class()# 第一次需要这段代码创建数据# b1 = orm_m2m.Book(name = "learn python with Alex",pub_date = "2015-05-05")# b2 = orm_m2m.Book(name = "learn Zhangbility with Alex",pub_date = "2015-09-05")# b3 = orm_m2m.Book(name = "learn hook up girls with Alex",pub_date = "2014-10-05")## a1 = orm_m2m.Author(name = "Alex")# a2 = orm_m2m.Author(name = "Jack")# a3 = orm_m2m.Author(name = "Rain")## # 建立第三张表的关联关系# b1.authors = [a1,a3]# b3.authors = [a1,a2,a3]## session.add_all([b1,b2,b3,a1,a2,a3])# session.commit()author_obj = session.query(orm_m2m.Author).filter(orm_m2m.Author.name == "alex").first()print(author_obj.name,author_obj.books)book_obj = session.query(orm_m2m.Book).filter(orm_m2m.Book.id == 2).first()print(book_obj,book_obj.authors)
多对多删除
删除数据时不用管boo_m2m_authors , sqlalchemy会自动帮你把对应的数据删除
import orm_m2mfrom sqlalchemy.orm import sessionmaker# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=orm_m2m.engine)#生成session实例,这里相当于cursorsession = Session_class()# author_obj = session.query(orm_m2m.Author).filter(orm_m2m.Author.name == "alex").first()# print(author_obj.name,author_obj.books)## book_obj = session.query(orm_m2m.Book).filter(orm_m2m.Book.id == 2).first()# book_obj.authors.remove(author_obj)## session.commit()author_obj = session.query(orm_m2m.Author).filter(orm_m2m.Author.name == "alex").first()print(author_obj.name,author_obj.books)session.delete(author_obj)session.commit()
若需要写入中文,需要将引擎这样写:
# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程 engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db?charset=utf8",encoding = "utf-8")
#一本书可以有多个作者,一个作者又可以出版多本书from sqlalchemy import Table, Column, Integer,String,DATE, ForeignKeyfrom sqlalchemy.orm import relationshipfrom sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy import create_enginefrom sqlalchemy.orm import sessionmakerBase = declarative_base()# 第三张表用这个创建,因为这个表不需要用ORM更新book_m2m_author = Table('book_m2m_author', Base.metadata, Column('book_id',Integer,ForeignKey('books.id')), Column('author_id',Integer,ForeignKey('authors.id')), )# 这种方式创建class Book(Base): __tablename__ = 'books' id = Column(Integer,primary_key=True) name = Column(String(64)) pub_date = Column(DATE) # # authors关联第三张表,不是真实的字段,通过secondary查询第三张表数据,Author通过backrep决定books反过来查询这张表Book authors = relationship('Author',secondary=book_m2m_author,backref='books') def __repr__(self): return self.nameclass Author(Base): __tablename__ = 'authors' id = Column(Integer, primary_key=True) name = Column(String(32)) def __repr__(self): return self.name# API接口为mysql与pymysql mysql用户名root 密码Choice123 主机是localhost 数据my_db,类型为utf-8,echo=True,执行这段代码的时候,会打印过程engine = create_engine("mysql+pymysql://root:Choice123@localhost/my_db?charset=utf8",encoding = "utf-8")# 创建表结构,调用Base类下的metadata方法,调用接口engine,这里是通过父亲调用儿子,生成子类的东西Base.metadata.create_all(engine)
import orm_m2mfrom sqlalchemy.orm import sessionmaker# 创建于数据库的会话session class,类似SQL里面的游标,但是这里返回给session的是个类,不是实例,所以下面需要实例化Session_class = sessionmaker(bind=orm_m2m.engine)#生成session实例,这里相当于cursorsession = Session_class()# b1 = orm_m2m.Book(name = "learn python with Alex",pub_date = "2015-05-05")b1 = orm_m2m.Book(name = "中文书本名称",pub_date = "2018-05-05")session.add(b1)session.commit()