03SQLALchemy外键约束

一,配置

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'))  #后面跟模块名)

猜你喜欢

转载自www.cnblogs.com/two-peanuts/p/10718805.html