flask-8
ORM之多对多
- 通过ORM创建两个表如article,tag(两表是多对多关系,即一篇文章可以有多个tag,一个tag可以有多个文章)
- 建立新表包含上述两个表的主键 article_tag = Table(“article_tag”,…)
- 任选一表,如一对多般建立两表的映射关系.relationshiop(“Article”,backref=“tags”)
- 增加一个选项relationship(“Article”,backref=“tags”,secondary=“article_tag”),与第三个表建立关系
# ---coding:utf-8----
# 文件名: manyToMany.py
# @Time:2020/4/21 15:40
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, table, Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
HOSTNAME = '120.24.*.*'
PORT = '3306'
DATABASE = 'school'
USERNAME = 'python'
PASSWORD = '*'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
engine = create_engine(DB_URI)
Base = declarative_base(engine)
session = sessionmaker(engine)()
article_tag = Table( #新建第三个表,包含两个表的主键,并将之都设为主键,注意Table是大写
"article_tag",
Base.metadata,
Column("article_id", Integer, ForeignKey('article.id'), primary_key=True),
Column("tag_id", Integer, ForeignKey('tag.id'), primary_key=True),
)
class Article(Base):
__tablename__ = "article"
id = Column(Integer, primary_key=True, autoincrement=True)
title = Column(String(50), nullable=False)
def __repr__(self):
return "标题是{}".format(self.title)
class Tag(Base):
__tablename__ = "tag"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50), nullable=False)
# articles = relationship("Article",backref='tags',secondary=article_tag)
article = relationship("Article", backref="tags", secondary=article_tag) # 任选一表为父表建立关系,此处选了Tag类,与Article类建立关系,反向查询使用tags,第三个表在此处标识
def __repr__(self):
return "标签名是{}".formate(self.name)
Base.metadata.drop_all()
Base.metadata.create_all()
article1 = Article(title="庭院深深血泪情仇智商大挑战")
article2 = Article(title="人生哲理山歌泪痕")
article3 = Article(title="仇杀情杀之二狗道士灵异破案")
tag1 = Tag(name="爱情")
tag2 = Tag(name="侦破")
tag3 = Tag(name="鬼神")
tag4 = Tag(name="生活")
article1.tags.append(tag1)
article1.tags.append(tag2)
article1.tags.append(tag4)
article2.tags.append(tag4)
article3.tags.append(tag1)
article3.tags.append(tag2)
article3.tags.append(tag3)
session.add_all([article1,article2,article3])
session.commit()
tag_q1 = session.query(Tag).filter(Tag.name=="爱情").first()
print(tag_q1) # 查出"爱情"标签
print(tag1.article) # "爱情"标签有几篇文章
article_q1 = session.query(Article).filter(Article.id==1).first()
print(article_q1) #查出第一篇文章
print(article_q1.tags) #反向查询查出该篇文章有几个标签
Flask-SQLAlchemy
一. 安装
pip install flask-sqlalchemy
二.连接
- 跟sqlalchemy一样,定义好数据库连接字符串DB_URI。
- 将这个定义好的数据库连接字符串DB_URI,通过
SQLALCHEMY_DATABASE_URI
这个键放到app.config
中。示例代码:app.config["SQLALCHEMY_DATABASE_URI"] = DB_URI
. - 使用
flask_sqlalchemy.SQLAlchemy
这个类定义一个对象,并将app
传入进去。示例代码:db = SQLAlchemy(app)
。
三.创建ORM模型: - 还是跟使用sqlalchemy一样,定义模型。现在不再是需要使用
delarative_base
来创建一个基类。而是使用db.Model
来作为基类。 - 在模型类中,
Column
、String
、Integer
以及relationship
等,都不需要导入了,直接使用db
下面相应的属性名就可以了。 - 在定义模型的时候,可以不写
__tablename__
,那么flask_sqlalchemy
会默认使用当前的模型的名字转换成小写来作为表的名字,并且如果这个模型的名字使用了多个单词并且使用了驼峰命名法,那么会在多个单词之间使用下划线来进行连接。虽然flask_sqlalchemy给我们提供了这个特性,但是不推荐使用。因为明言胜于暗喻
四.将ORM模型映射到数据库:
- db.drop_all()
- db.create_all()
五.使用session:
以后session也不需要使用sessionmaker
来创建了。直接使用db.session
就可以了。操作这个session的时候就跟之前的sqlalchemy
的session
是iyimoyiyang的。
六.查询数据:
如果查找数据只是查找一个模型上的数据,那么可以通过模型.query
的方式进行查找。query
就跟之前的sqlalchemy中的query方法是一样用的。示例代码如下:
users = User.query.order_by(User.id.desc()).all()
print(users)
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
HOSTNAME = '120.24.144.212'
PORT = '3306'
DATABASE = 'school'
USERNAME = 'python'
PASSWORD = '520ljx'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE) #指定编码方式
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI # 应用到flask 配置文件中
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False #一有改变就触发信号通知 比较耗内存 可以把它关掉
db = SQLAlchemy(app) #创建Flask_SQLAlchemy实例
class UserModel(db.Model):
__tablename__ = "user_model" #可以不写,自动生成usermodel或user_model,推荐要写
id = db.Column(db.Integer,primary_key=True,autoincrement=True) #Column,Integer等变成db的方法
username = db.Column(db.String(50),nullable=False)
def __repr__(self):
return "用户名是:{}".format(UserModel.username)
class ArticleModel(db.Model):
__tablename__ = "article_model"
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
title = db.Column(db.String(50),nullable=False)
uid = db.Column(db.Integer,db.ForeignKey('user_model.id'))
author = db.relationship("UserModel",backref="articles") #除了使用db实例,其他一样
# db.drop_all()
# db.create_all()
#
# u1 = UserModel(username="周杰伦")
# a1 = ArticleModel(title="什么堡")
#
# a1.author=u1
#
# db.session.add(a1)
# db.session.commit()
#查询:
user = UserModel.query.filter(UserModel.username=="周杰伦").first()
article1 = ArticleModel.query.filter(ArticleModel.title=="什么堡").first()
db.session.delete(user)
db.session.commit()
# print(user,article1)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()