一,配置
1,SQLALchemy的配置单独使用config.py文件
2,满足如下要求:
#dialect+driver://username:password@host:port/database
具体说明如下:
# dialect:是数据库的实现,比如MySql,SQLlite,且转换为小写 # driver:对应的驱动,比如MySql的驱动是MySqldb # username:连接数据库的用户名 # password:密码 # host:连接数据库的域名 # port:数据库监听的端口号 # database:是连接的数据库的名字,创建数据库语句为: SQL语句:"""create database db_demo1(database_name) charset utf8""" # 如果以上输出了1则说明SQLAlchemy能成功连接到数据库。 DIALECT = "mysql" DRIVER = "mysqldb" USERNAME = "root" PASSWORD = '1234' HOST = "127.0.0.1" PORT = "3306" DATABASE = "db_demo3" SQLALCHEMY_DATABASE_URI="{}+{}://{}:{}@{}:{}/{}".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASE) """指定一个名为SQLALCHEMY_DATABASE_URI的固定变量,注意是固定的写法""" SQLALCHEMY_TRACK_MODIFICATIONS =False
3,在主程序中引用并配置:
#引用 from flask import Flask from flask_sqlalchemy import SQLAlchemy import config #配置 app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app)
二,具体使用
1,数据库创建与删除
2,表的创建
class User(db.Model): __tablename__ = "user" id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(100),nullable=False) class Article(db.Model): __tablename__ = "article" id = db.Column(db.Integer,primary_key=True,autoincrement=True) title = db.Column(db.String(100),nullable=False) content = db.Column(db.Text,nullable=False) author_id = db.Column(db.Integer,db.ForeignKey('user.id')) #后面跟表名
db.create_all() #创建后一定记得这一步
创建后用Navicat查看为:
创建两个空表后需要写入数据:
# user1 = User(username="zy") # db.session.add(user1) # db.session.commit() # # user2 = User(username="ly") # db.session.add(user2) # db.session.commit() # # article1 = Article(title="zy1", content="zy1",author_id=1) # article2 = Article(title="zy2", content="zy2", author_id=1) # article3 = Article(title="ly1", content="ly1", author_id=2) # article4 = Article(title="ly2", content="ly2", author_id=2) # db.session.add(article1) # db.session.add(article2) # db.session.add(article3) # db.session.add(article4) # db.session.commit()
User模块下user表的结构应该是:
id | username |
1 | zy |
2 | ly |
Article模块下articler表的结构应该是:
id | title | content | author_id |
1 | zy1 | zy1 | 1 |
2 | zy2 | zy2 | 1 |
3 | ly1 | ly1 | 2 |
4 | ly2 | ly2 | 2 |
3,增删改查(这里代码没怎么修改,主要看黄字部分)
def hello_world(): # 数据的增加: # article1 = Article(title="a",content="A") # db.session.add(article1) # # 数据的增删改查都是在“session”里做的,但是它和web中的“session”不一样。 # db.session.commit() #每一步的提交都不能忘记 # 数据的查: # # select * from article where title = "aaa"; # result = Article.query.filter(Article.title == "a")[0] # print(result.title,result.content) # # query来源于db.Model,查找都是基于query的。 # 数据的改: # # 1,先把你要更改的数据查找出来 # article1 = Article.query.filter(Article.title == "a").first() # # 2,吧这条数据,你需要的地方进行修改 # article1.title = "new title" # # 3,做事务的提交 # db.session.commit() #数据的删: # 1,把需要删除的数据查找出来 article1 = Article.query.filter(Article.title == "a").first() # 2,把这条数据删除 db.session.delete(article1) # 3,做事务的提交 db.session.commit() return 'Hello World!'
4,外键约束
对于以下两个需求来讲,实现如下,这是属于常规的且不方便的做法:
# 方案一: # # 找到标题为“zy1”的文章的作者 # result1 = Article.query.filter(Article.title == "zy1").first() # result2 = User.query.filter(User.id == result1.author_id).first() # print(result2.username) # # # 找到zy用户写过的所有文章 # result3 = User.query.filter(User.username == "zy").first() # result4 = Article.query.filter(Article.author_id == result3.id).all() #all # for i in result4: # print(i.title)
可以看到二.2部分只有一个单纯的外键关系(“author_id = db.Column(db.Integer,db.ForeignKey('user.id')) #后面跟表名”),对于上述两个操作不太方便,那么我们如何让上述操作更简单呢?
就在原源代码上加入黄代码那句:
class User(db.Model): __tablename__ = "user" id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(100),nullable=False) class Article(db.Model): __tablename__ = "article" id = db.Column(db.Integer,primary_key=True,autoincrement=True) title = db.Column(db.String(100),nullable=False) content = db.Column(db.Text,nullable=False) author_id = db.Column(db.Integer,db.ForeignKey('user.id')) #跟表名 author = db.relationship('User', backref=db.backref('articles')) #后面跟模块名
# 给“Article”这个模型添加一个“author”属性,可以访问这篇文章的作者的数据,像普通访问一样。
# “backref”是定义反向引用,是通过“User.articles”这个模型访问这个模型的所有文章。
db.create_all()
注意加入的黄代码会改变表结构,这时候需要重建表,即drop操作和create就行。
对于之前两个操作而言可以有如下简便且实用操作,下面代码黄色部分重点关注:
# 方案二 # 找到标题为“zy1”的文章的作者(与下面的一段反向对应。)。 # article = Article.query.filter(Article.title == "zy1").first() # print(article.author.username) # 找到zy用户写过的所有文章 user = User.query.filter(User.username == "zy").first() result = user.articles #这里的result是返回的所有文章,所以是个list类型,这就是backref带来的反向引用的作用 print("{}的文章:".format(user.username)) for i in result: print(i,"Title:",i.title,"Content:",i.content)
相当于在Article模块中从A表变为B表:
- A表:
id |
title |
content |
author_id |
- B表:
是是
id |
title |
content |
author_id |
author (=db.relationship('User', backref=db.backref('articles')) #后面跟模块名) |