python—sqlalchemy简单使用方法,一对多,多对多,双向关系教程
数据库的连接
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:123456@localhost:5432/postgres' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app)
其中
postgres
:数据库用户名
123456
:数据库密码
localhost
:为数据库的host
5432
:为数据库的端口
postgres
:数据库名称
表的创建
在 SQLAlchemy 中定义模型时,可以使用许多属性来规定表的字段的属性和行为,这些属性有很多,具体如下:
Column: 声明一个列。
String: 字符串类型,参数为指定字符串的最大长度,通常用于存储短文本、用户名等字符串类型的数据。
Text: 文本类型,用于存储大块文本。
Integer: 整数类型,通常用于存储数值类型的 ID 编号等。
Float: 浮点数类型,用于存储浮点类型的数据。
Boolean: 布尔类型,用于存储布尔类型的数据。
DateTime: 日期和时间类型,用于存储日期和时间信息。
Date: 日期类型,用于存储日期信息。
Time: 时间类型,用于存储时间信息。
ForeignKey: 外键类型,用于定义外键关系。
relationship: 定义 ORM 关系模型中的关系类型。
back_populates: 定义反向引用的属性名称。
primary_key=True: 指示该列是主键列。
unique=True: 指定该列的值必须是唯一的。
default: 指定该列的默认值。
nullable=False: 指定该列的值不能为空。
上述仅是一部分常用的属性,有些属性只针对某些类型的数据,具体使用时需要根据需要选择。
表的增删改查
# 创建数据库表 with app.app_context(): db.create_all() # 添加新用户到数据库 user1 = User(username='alice', email='alice@example.com') user2 = User(username='bob', email='bob@example.com') db.session.add(user1) db.session.add(user2) db.session.commit() # 查询所有用户 with app.app_context(): # 查询所有用户 users = User.query.all() for user in users: print(user.username, user.email) # 根据 id 查询用户 user = User.query.get(1) print(user.username, user.email) # 根据 name 查询用户 user = User.query.filter_by(name='Alicee').first() print(user.username, user.email) # 删除一条记录 user = session.query(User).filter_by(id=1).first() session.delete(user) # 提交更改 session.commit() # 删除所有记录 session.query(User).delete() # 提交更改 session.commit() # 更新一条记录 user = session.query(User).filter_by(id=1).first() user.name = 'new name' # 提交更改 session.commit() # 更新所有记录 session.query(User).update({'name': 'new name'}) # 提交更改 session.commit()
总结一下:
增加操作:
session.add(obj): 向会话中添加一个对象。
session.bulk_save_objects(list): 批量向数据库中插入多条记录。
查询操作:
session.query(Model).filter(condition1, condition2, ...).all(): 查询满足给定条件的所有记录。
session.query(Model).filter(condition1, condition2, ...).first(): 查询满足给定条件的第一条记录。
session.query(Model).filter(condition1, condition2, ...).paginate(page, per_page): 分页查询满足给定条件的记录。
session.query(Model).group_by(column).all(): 根据指定列进行分组查询。
更新操作:
session.query(Model).filter(condition).update({column: value}): 更新满足给定条件的记录的某个列的值。
删除操作:
session.query(Model).filter(condition).delete(): 删除满足给定条件的所有记录。
session.query(Model).filter(condition).first().delete(): 删除满足给定条件的第一条记录。
这些指令可以组合运用,实现更加复杂的数据操作。在实际使用中,需要先根据需求选择恰当的查询条件,并在此基础上采用增、删、改等操作。同时,也要注意在操作完成后及时提交事务,以保证持久化到数据库中。
一对多的关系
首先我们创建父母与孩子的表
关系口诀:
多方:Foreignkey
一方:relationship
# 父母表为一 class Parent(db.Model): __tablename__ = "parent" id = Column(Integer, primary_key=True) name = Column(String(1024)) childs = relationship("Child", backref="parent") # 儿童表为多 class Child(db.Model): __tablename__ = "child" id = Column(Integer, primary_key=True) name = Column(String(1024)) parent_id= Column(Integer, ForeignKey("parent.id")) if __name__ == '__main__': with app.app_context(): db.drop_all() db.create_all()
我们来添加父母与子女的例子
"""添加关系子女测试""" with app.app_context(): p1 = Parent(id=1, name="张爸爸") db.session.add(p1) db.session.commit() with app.app_context(): c1=Child(id=1,name="张三",parent_id=1) c2=Child(id=2,name="张四",parent_id=1) db.session.add(c1) db.session.add(c2) db.session.commit()
最后我们通过子女的关系打印出父母的名字
with app.app_context(): childs=db.session.query(Child).filter(Child.parent_id==1).all() for child in childs: print(child.id,child.name,child.parent_id,child.parent.name)
结果为:
1 张三 1 张爸爸
2 张四 1 张爸爸
多对多的关系
我们建立一个学生与课程的表
一个学生对应多个课程
一个课程也有多个学生上课
我们需要引入第三张表作为中间表
# 中间表 class StudentToCourse(db.Model): __tablename__ = "student_to_course" id = db.Column(db.Integer,primary_key=True) student_id = db.Column(db.Integer, db.ForeignKey("student.id")) course_id = db.Column(db.Integer, db.ForeignKey("course.id")) # 学生表 class Student(db.Model): __tablename__ = "student" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), nullable=False) courses = db.relationship("Course", secondary="student_to_course", backref="student") # 课程表 class Course(db.Model): __tablename__ = "course" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), nullable=False) teacher = db.Column(db.String(64))
现在我们创建数据库的实例子
with app.app_context(): s1=Student(id="1",name="张三") s2 = Student(id="2", name="李四") s3 = Student(id="3", name="王五") s=[s1,s2,s3] db.session.add_all(s) db.session.commit() c1=Course(id="1",name="python实训",teacher="张伟") c2=Course(id="2",name="sql实训",teacher="张一山") db.session.add(c1) db.session.add(c2) db.session.commit() t1=StudentToCourse(student_id=1,course_id=1) t2=StudentToCourse(student_id=1,course_id=2) t3=StudentToCourse(student_id=2,course_id=1) t4=StudentToCourse(student_id=2,course_id=2) t=[t1,t2,t3,t4] db.session.add_all(t) db.session.commit()
现在我们通过学生表来查询学生id为1的同学上的那几门课:
with app.app_context(): student = db.session.query(Student).filter(Student.id == 1).first() print(student.id, student.name) for course in student.courses: print(course.id, course.name)
双向关系
建立一个学生表和班级表
一个学生在多个班级里面上课
一个班级里面有多个学生上课
我们建立一个双向关系,可以相互访问
class ClassStudent(db.Model): __tablename__ = 'class_student' class_id = Column(Integer, ForeignKey('class.id'), primary_key=True) student_id = Column(Integer, ForeignKey('student.id'), primary_key=True) class Class(db.Model): __tablename__ = 'class' id = Column(Integer, primary_key=True) students = relationship("Student", secondary="class_student", back_populates="classes") """简而言之,backref和back_populates的区别就是,back_populates使用必须要两个表都要使用,当id指定了相应的用户,他们就相当于两个电脑通信了,可以共享对方的相应的属性。""" """来自博客:https://blog.csdn.net/sinat_41667855/article/details/118729091""" class Student(db.Model): __tablename__ = 'student' id = Column(Integer, primary_key=True) classes = relationship("Class", secondary="class_student", back_populates="students") if __name__ == '__main__': with app.app_context(): db.drop_all() db.create_all()
让我们来建立实例
with app.app_context(): s1 = Student(id=1) s2 = Student(id=2) s3 = Student(id=3) s4 = Student(id=4) s = [s1, s2, s3, s4] db.session.add_all(s) db.session.commit() c1 = Class(id=1) db.session.add(c1) db.session.commit() cs1 = ClassStudent(class_id=1, student_id=1) cs2 = ClassStudent(class_id=1, student_id=2) cs3 = ClassStudent(class_id=1, student_id=3) cs4 = ClassStudent(class_id=1, student_id=4) cs=[cs1,cs2,cs3,cs4] db.session.add_all(cs) db.session.commit()
让我们把内容打印出来
with app.app_context(): # 通过学生访问该学生所在的班级 student = db.session.query(Student).filter(Student.id == 1).first() print(student.id) for classes in student.classes: print(classes.id) # 通过班级访问所有在该班级的学生 classs = db.session.query(Class).filter(Class.id == 1).first() print(classs.id) print("___________________________________________________________") for students in classs.students: print(students.id)
本文作者:岳宗柯
本文链接:https://www.cnblogs.com/yuezongke/p/17722308.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步