flask-day8:ORM之多对多|Flask-SQLAlchemy

ORM之多对多

  1. 通过ORM创建两个表如article,tag(两表是多对多关系,即一篇文章可以有多个tag,一个tag可以有多个文章)
  2. 建立新表包含上述两个表的主键 article_tag = Table(“article_tag”,…)
  3. 任选一表,如一对多般建立两表的映射关系.relationshiop(“Article”,backref=“tags”)
  4. 增加一个选项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
二.连接

  1. 跟sqlalchemy一样,定义好数据库连接字符串DB_URI。
  2. 将这个定义好的数据库连接字符串DB_URI,通过SQLALCHEMY_DATABASE_URI这个键放到app.config中。示例代码:app.config["SQLALCHEMY_DATABASE_URI"] = DB_URI.
  3. 使用flask_sqlalchemy.SQLAlchemy这个类定义一个对象,并将app传入进去。示例代码:db = SQLAlchemy(app)
    三.创建ORM模型:
  4. 还是跟使用sqlalchemy一样,定义模型。现在不再是需要使用delarative_base来创建一个基类。而是使用db.Model来作为基类。
  5. 在模型类中,ColumnStringInteger以及relationship等,都不需要导入了,直接使用db下面相应的属性名就可以了。
  6. 在定义模型的时候,可以不写__tablename__,那么flask_sqlalchemy会默认使用当前的模型的名字转换成小写来作为表的名字,并且如果这个模型的名字使用了多个单词并且使用了驼峰命名法,那么会在多个单词之间使用下划线来进行连接。虽然flask_sqlalchemy给我们提供了这个特性,但是不推荐使用。因为明言胜于暗喻

四.将ORM模型映射到数据库:

  1. db.drop_all()
  2. db.create_all()

五.使用session:
以后session也不需要使用sessionmaker来创建了。直接使用db.session就可以了。操作这个session的时候就跟之前的sqlalchemysession是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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值