博客
关于我
ORM sqlachemy学习
阅读量:795 次
发布时间:2023-02-26

本文共 5265 字,大约阅读时间需要 17 分钟。

ORM与SQLAlchemy入门讲解

1. ORM(Object Relational Mapping)简介

ORM(对象关系映射)是一种将数据库表结构与编程语言对象模型进行映射的技术。由于现代应用程序通常使用面向对象的编程语言(如Python)进行开发,而传统数据库则基于关系型结构,这导致了编程逻辑与数据存储逻辑之间的不一致。ORM的目标是通过自动化将编程模型与数据库模型统一,使得开发者可以使用更高层次的抽象化操作,从而简化数据库交互。

ORM的优点:

  • 隐藏了数据访问细节:通过封闭式的数据库交互方式,开发者无需直接操作SQL,从而提高了开发效率。
  • 简化数据结构构建:ORM框架能够自动处理数据库表结构的映射,使得代码更加简洁易读。
  • ORM的缺点:

  • 性能损失:由于 ORM 需要在运行时处理数据映射和关联,早期 ORM 框架的性能较差,但随着技术进步,这种问题已得到有效缓解。
  • 自动化的代价: ORM 需要维护大量的映射逻辑,这可能导致维护成本增加。

  • 2. SQLAlchemy简介

    SQLAlchemy 是 Python 编程语言下的一款流行 ORM 框架,它建立在数据库API之上,通过关系对象映射将编程模型与数据库操作统一。SQLAlchemy 的核心思想是将 Python 对象与数据库表结构进行映射,从而通过编写高层次的 Python 代码直接操作数据库。

    SQLAlchemy 的基本原理

    数据库表可以看作一个二维的数据结构,Python 类型可以用来表示数据库表中的数据。例如,以下代码展示了如何将数据库表转换为 Python 类型:

    1 class User(object):
    2 def __init__(self, id, name):
    3 self.id = id
    4 self.name = name
    5
    6 [User('1', 'woz'), User('2', 'wyb'), User('3', 'alex')]

    这种映射方式就是 ORM 的核心功能:通过自定义类定义数据库表结构,将关系型数据库转换为面向对象的编程模型。

    SQLAlchemy 安装

    要使用 SQLAlchemy,需要先安装相应的包:

    pip3 install SQLAlchemy

    3. SQLAlchemy 的内部处理

    1. 依赖第三方数据库API

    SQLAlchemy 本身无法直接操作数据库,它需要依赖第三方数据库驱动(如 mysqldbpymysqlcx_Oracle 等)来与数据库进行通信。这些驱动通过 dialect 模块实现与数据库API的对接,从而支持多种数据库类型如 MySQL、PostgreSQL、Oracle等。

    2. 内部处理机制

    SQLAlchemy 的核心组件包括:

    • Engine/ConnectionPooling:用于管理数据库连接,支持连接池化,以提高数据库操作效率。
    • Dialect:定义了数据库API的具体实现方式,根据数据库类型选择合适的连接方式。

    4. SQLAlchemy 的使用

    1. 创建表与数据插入

    通过 SQLAlchemy,可以通过编写类和操作 session 对象来创建和管理数据库表结构。以下是一个典型的操作示例:

    1 from sqlalchemy.ext.declarative import declarative_base
    2 from sqlalchemy.orm import sessionmaker
    3 from sqlalchemy import Column, Integer, String
    4 # 创建数据库会话
    5 engine = create_engine("mysql+pymysql://root:root@127.0.0.1:3306/wyb", encoding="utf-8")
    6 Base = declarative_base()
    7 Session_class = sessionmaker(bind=engine)
    8 Session = Session_class()
    9 # 定义用户表
    10 class User(Base):
    11 __tablename__ = 'user'
    12 id = Column(Integer, primary_key=True)
    13 name = Column(String(32))
    14 password = Column(String(64))
    15 # 创建表结构
    16 Base.metadata.create_all(engine)
    17 # 插入数据
    18 user_obj = User(name="wyb", password="666")
    19 Session.add(user_obj)
    20 Session.commit()

    2. 数据库操作(增删改查)

    通过 SQLAlchemy,可以对数据库表进行 CRUD 操作。以下是一个完整的示例:

    def create_table():
    Base.metadata.create_all(engine)
    def insert(user_obj):
    print("插入数据:")
    print(user_obj)
    Session.add(user_obj)
    Session.commit()
    def select():
    print("查询数据:")
    # 查询单条数据
    data = Session.query(User).filter_by(name="woz").first()
    print("name=woz: ", data)
    data = Session.query(User).filter_by(id=1).first()
    print("id=1: ", data)
    # 查询所有数据
    print("表中所有数据: ", Session.query(User.id, User.name).all())
    # 多条件查询
    objs = Session.query(User).filter(User.id > 0).filter(User.id < 3).all()
    print("id为0到3之间的数据: ", objs)
    def delete():
    print("删除数据:")
    result = Session.query(User).filter(User.name == 'alex').first()
    print(result)
    Session.delete(result)
    Session.commit()
    def update():
    print("更新数据:")
    my_user = Session.query(User).filter_by(name="wyb").first()
    my_user.name = "wyb666"
    my_user.password = "wyb666"
    print(my_user)
    Session.commit()

    5. 关系与多对多操作

    外键关联

    通过定义 relationship,可以实现对象间的关联关系。以下是一个简单的外键示例:

    class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    email_address = Column(String(32), nullable=False)
    user_id = Column(Integer, ForeignKey('user.id'))
    user = relationship("User", backref="address")
    # 创建表结构
    def create_table():
    Base.metadata.create_all(engine)
    # 查询关联对象
    objs = Session.query(User).all()
    add_objs = Session.query(Address).all()
    for i in objs:
    print(i.address)
    for add_obj in add_objs:
    print(add_obj.user.name)

    多对多联系

    通过创建中间表和使用 relationship,可以实现多对多的关系。以下是一个多对多联系的示例:

    # 创建中间表
    student_m2m_course = Table('student_m2m_course', Base.metadata,
    Column('student_id', Integer, ForeignKey('student.id')),
    Column('course_id', Integer, ForeignKey('course.id')))
    class Student(Base):
    __tablename__ = 'student'
    id = Column(Integer, primary_key=True)
    name = Column(String(64))
    attach = relationship('Attach', secondary=student_m2m_course, backref='students')
    class Course(Base):
    __tablename__ = 'course'
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    # 创建数据
    a1 = Student(name="12342ds")
    a2 = Student(name="222")
    a3 = Student(name="666")
    b1 = Course(name="跟wyb学Python")
    b2 = Course(name="跟wyb学把妹")
    b3 = Course(name="跟wyb学装逼")
    a1.courses = [b1, b2]
    a2.courses = [b2, b3]
    a3.courses = [b1, b3]
    Session.add_all([a1, a2, a3, b1, b2, b3])
    Session.commit()

    6. 其他操作

    回滚与统计分组

    通过 Session.rollback() 可以回滚事务,确保数据一致性。统计分组可以通过 group_by 方法实现:

    # 回滚示例
    Session.rollback()
    print(Session.query(User).filter(User.name.in_(['Jack', 'rain'])).all())
    # 统计分组
    print(Session.query(func.count(User.name), User.name).group_by(User.name).all())

    多对多删除

    删除多对多关系时,可以直接操作对象:

    student_obj = Session.query(Student).filter_by(name="12342ds").first()
    course_obj = Session.query(Course).filter_by(name="跟wyb学把妹").first()
    student_obj.courses.remove(course_obj)
    Session.delete(course_obj)
    Session.commit()

    7. 学员管理系统需求

    需求概述

  • 用户角色

    • 讲师:管理班级,创建上课纪录,批改成绩。
    • 学员:提交作业,查看成绩,支持多班级报名。
  • 功能模块

    • 讲师视图:
      • 班级管理
      • 上课纪录创建
      • 成绩批改
    • 学员视图:
      • 作业提交
      • 成绩查询
      • 多班级报名

  • 通过以上内容,可以看到 SQLAlchemy 在数据库操作中的强大能力,如何通过 ORM 将复杂的数据库操作简化为易于管理的代码。无论是表结构创建、数据操作,还是复杂的关联关系管理,SQLAlchemy 都能提供强有力的支持。

    转载地址:http://nzvfk.baihongyu.com/

    你可能感兴趣的文章
    org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement profile
    查看>>
    sql查询中 查询字段数据类型 int 与 String 出现问题
    查看>>
    org.apache.commons.beanutils.BasicDynaBean cannot be cast to ...
    查看>>
    org.apache.dubbo.common.serialize.SerializationException: com.alibaba.fastjson2.JSONException: not s
    查看>>
    sqlserver学习笔记(三)—— 为数据库添加新的用户
    查看>>
    org.apache.http.conn.HttpHostConnectException: Connection to refused
    查看>>
    org.apache.ibatis.binding.BindingException: Invalid bound statement错误一例
    查看>>
    org.apache.ibatis.exceptions.PersistenceException:
    查看>>
    org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned
    查看>>
    org.apache.ibatis.type.TypeException: Could not resolve type alias 'xxxx'异常
    查看>>
    org.apache.poi.hssf.util.Region
    查看>>
    org.apache.xmlbeans.XmlOptions.setEntityExpansionLimit(I)Lorg/apache/xmlbeans/XmlOptions;
    查看>>
    org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /
    查看>>
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:processDebugManifest'
    查看>>
    org.hibernate.HibernateException: Unable to get the default Bean Validation factory
    查看>>
    org.hibernate.ObjectNotFoundException: No row with the given identifier exists:
    查看>>
    org.springframework.amqp.AmqpConnectException:java.net.ConnectException:Connection timed out:connect
    查看>>
    org.springframework.beans.factory.BeanDefinitionStoreException
    查看>>
    org.springframework.boot.context.properties.ConfigurationBeanFactoryMetadata
    查看>>
    org.springframework.boot:spring boot maven plugin丢失---SpringCloud Alibaba_若依微服务框架改造_--工作笔记012
    查看>>