SQLAlchemy是Python编程语言下的一款开源软件,提供了SQL工具包和ORM工具,使用MIT许可证发行。
SQLAlchemy采用简单的Python语言,为了搞笑和高性能数据库访问设计,实现了完整的企业级持久模型。
SQLAlchemy首次发行于2006年2月,并迅速成为Python社区中最广泛应用的ORM工具直以,不亚于Django的ORM框架
Flask-SQLAlchemy是在Flask框架上的一个扩展,对SQLAlchemy进行了封装,目的简化于在Flask中的SQLAlchemy的使用,提供了有用的默认值和额外的助手来完整简单的日常任务。
在Flask中使用Flask-SQLAlchemy需要进行配置,主要配置有以下几项:
SQLALCHEMY_DATABASE_URI
数据库的连接信息
Postgres:
postgresql://user:password@localhost/mydatabase
MySQL:
mysql://user:password@localhost/mydatabase
Oracle:
oracle://user:[email protected]:1521/sidname
SQLite (注意开头的四个斜线):
sqlite:absolute/path/to/foo.db
SQLALCHEMY_TRACK_MODIFICATIONS
在Flask中是否追踪数据修改
SQLALCHEMY_ECHO
显示生成的SQL语句,可用于调试
这些配置参数需要放在Flask的应用配置(app.config)中。
from flask import Flask
app = Flask(__name__)
class Config(object):
# 表示连接数据库的信息
SQLALCHEMY_DATABASE_URI='mysql://root:mysql@localhost/abc'
# 如果不设置,不会报错,只会提示警告信息,如果要关闭警告信息,可以设置为True或False
# True表示跟踪数据库信号变化,会影响计算机的性能,消耗内存,
SQLALCHEMY_TRACK_MODIFICATION = False
# 显示生成的SQL语句,可用于调试
SQLALCHEMY_ECHO = True
app.config.from_object(Config)
其他配置信息自行百度。
这个内容也自行百度吧!!。
首先创建SQLAlchemy对象
方式一:
app = Flask(__name__)
db = SQLAlchemy(app)
方式二:
db = SQLalchemy()
db.init_app(app)
定义模型类
class User(db.Model):
__table__name = 'user_basic'
class STATUS:
ENABLE = 1
DISABLE = 0
id = db.Column('user_id',db.Integer,primary_key=True,doc='用户id')
name = db.Column(db.String,doc='用户昵称')
mobile = db.Column(db.String,doc='手机号')
''''''
user = User(name='wtt',mobile='13666666666')
db.session.add(user)
db.session.commit()
也可以使用批量添加对象语句
db.session.add([user,user1,user2])
db.session.commit()
all() ,查询所有,返回列表
SQL:
select user_id,name,mobile from user_basic;
ORM:
User.query.all()
first() ,查询第一个,返回对象
SQL:
select user_id,name,mobile from user_baisc limit 1;
ORM:
User.query.first()
get() , 根据主键ID获取对象,若对象不存在会返回空
SQL:
select user_id,name,mobile from user_basic where id = 1;
ORM:
User.query.get(1)
SQLAlchemy原生查询
# 把模型类作为参数传给数据库会话对象
# session表述数据库会话对象,封装了对数据库的基本操作,包括数据回滚、提交删除等。
db.session.query(User).all()
db.session.query(User).first()
db.session.query(User).get(1)
filter_by ,过滤查询
SQL:
select user_id,name,mobile from user_basic where mobile='1366666666'
ORM:
# 直接使用filter_by返回的是查询对象
User.query.filter_by(mobile='13666666666’)
#
# 对查询使用执行器;all表示列表;first表示一个
User.query.filter_by(mobile='13666666666').first()
filter, 过滤查询
ORM:
# 直接使用filter,返回的是查询对象
User.query.filter(User.mobile=='13666666666')
#
User.query.filter(User.mobile=='13666666666').fitst()
filter_by和filter的区别:
逻辑与、或、非 (与和非用到的非常少,因为默认就是and,而非的话则可以用!=或<>)
from sqlalchemy import and_,or_,not_
ORM:
User.query.filter(and_(User.name=='wtt'),User.id<=3).all()
User.query.filter(or_(User.name.startswith('w'),User.id>=10)).all()
User.query.filtet(not_(User.id==1))
offset和limit
# 从表中第二条记录(包括第二条)开始往后显示
User.query.offset(1).all()
# 显示表中第一条记录
User.query.limit(1).all()
# 显示表中的3,4,5条数据
User.query.limit(3).offset(2).all()
order_by ,排序查询 默认升序asc,降序是desc
User.query.order_by(User.id.desc()).all()
User.query.filter(User.name.startswith('w').order_by(User.id.desc())).offset(1).limit(1).all()
为了提高查询效率,建议将这种复杂查询拆分成几条简单的查询
q = User.query.filter(User.name.startswith('w'))
q = q.query.order_by(User.id.desc())
q = q.offset(1).limit(1)
a = q.all()
# 默认是全字段查询
User.query.filter(User.id>=30).all()
# 优化查询 ,查询指定的字段
from sqlalchemy.orm import load_only
User.query.options(load_only(User.id,User.name)).filter(User.id>=30).all()
# 需求:用户id为1的粉丝数?
SQL:
select user_id,count(targe_user_id) from user_realtion where id = 1;
# 所有用户的粉丝数,分组查询
select user_id,count(target_user_id) from user_realtion group_by user_id
ORM:
Relation.query.filter(Relaion.User_id==1).group_by(Relation.User_id).all()
db.session,query(Relation.User_id,func.count(Relation.target_user_id)).group_by(Relation.user_id).all()
class User(db.Model):
# 一方定义关系,参数一为要关系的模型类,backref代表可以反向引用回来
profile = db.relationship('UserProfile',uselist=False,backref='p')
follow = db.relationship('Relation',userlist=False,backref='f')
class Userprofile(db.model):
```
# 另外一方定义外键,不是数据库中的外键,仅仅是关联查询时的属性,在数据库中没有实体
# 如果通过迁移的形式创建表,外键有实体;
id = db.Column('user_id',db.Integet,db.foreign('user_basc.user_id'),doc='用户ID')
class Relation(db.mobile):
user_id = db.Column(db.Integet,db.foreign('user_basic.user_id'),doc='用户ID')
# 测试 正向查询 从User到Relation
user = User.query.filter(User.name=='wtt').first()
# 使用关系选项,查询该用户关注了那些人
user.follow
# 反向查询 ,从Relation到User
rel = Relation.query.get(1)
# 使用反向引用 查询该用户id是那个用户
rel.f
class User(db.Model):
profile = db.relationship('UserProfile',primaryjoin('User.id==foreign(Relation.id)'))
user = User.query.get(10)
user.profile
# 需求:根据手机号查询用户的粉丝数
SQL:
select user_relation.user_id,count(Relation.target_user_id) from Relation join User on User.id=Relation.user_id where mobil='13666666666'
ORM:指定字段、连表查询、计数
from sqlalchemy.orm import load_only,contains_eager
user = User.query.join(User.follow).options(load_only(User.id,User.name).contaings_eager(User.follow).load_only(Relation.user_id,Relation.target_user_id)).filter(User.mobile=='13666666666').all()
user[0].follow
方式一:
user = User.query.get(1)
user.name='wttaa'
db.session.add(user)
db.session.commit()
方式二:
User.query.filter(User.id==1).update({'name'=='en'})
db.session.commit()
方式一:
user = User.query.get(1)
db.session.delete(user)
db.session.commit()
方式二:
User.query.filter(User.id==1).delete()
db.session.commit()
environ = {'wsgi.version':(1,0), 'wsgi.input': '', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/', 'SERVER_NAME': 'flask python', 'wsgi.url_scheme': 'http', 'SERVER_PORT': '80'}
# 使用请求上下文环境
with app.request_context(environ):
try:
user = User(mobile='13666666666',name='wtt')
db.session.add(user)
db.session.flush() # 将数据刷新到数据库中
profile = UserProfiel(id=user.id)
db.session.add(profie)
db.session.commit()
except:
db.session.rollback()