zoukankan      html  css  js  c++  java
  • SQLAlchemy

    一、ORM技术简介

    1.1、ORM:Object-Relational Mapping,把关系数据库的表结构映射到对象上,简单的说,ORM 将数据库中的表与面向对象语言中的类建立了一种对应关系。这样,我们要操作数据库,数据库中的表或者表中的一条记录就可以直接通过操作类或者类实例来完成。

    ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换

    1.2、如果我们从数据库查出来几条数据,需要你在python中表示出来,如果你没有接触过ORM技术,你或许会使用下面的形式来存储这个数据:

    [
        (1, ‘ling’),
        (2, ‘shang’),
        (3, ‘huo’),
    ]

    如果你想知道表结构是什么样的,是不是就费劲了,如果你想快速的出其中的元素,就需要听听ORM的思想了。

    1.3、数据库中每次查出来的数据都用一个类表示,这个类的属性和数据库中表的字段一一对应。多条数据,就是一个list,每一行数据都是一个类来表示,如下所示:

    class User(object):
        def __init__(self, id, name):
            self.id = id
            self.name = name
    [
        User(1, “ling”),
        User(2, “shang”),
        User(3, “huo”),
    ]

    当我们需要获得id,或者name的时候,只需要通过循环获取到对象,直接通过user1.id或者user1.name就可以获取到id和name的属性。并且使得数据的存取非常的规范,这样ORM架构应用而生。

    二、SQLAlchemy

    在Python中,最有名的ORM框架是SQLAlchemy

    # 导入:
    from sqlalchemy import Column, String, create_engine
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.declarative import declarative_base

    # 创建对象的基类:
    Base = declarative_base()

    # 定义User对象:
    class User(Base):
    # 表的名字:
    __tablename__ = 'user'

    # 表的结构:
    id = Column(String(20), primary_key=True)
    name = Column(String(20))

    # 初始化数据库连接:
    engine = create_engine('mysql+mysqlconnector://root:password@localhost:3306/test')
    # 创建DBSession类型:
    DBSession = sessionmaker(bind=engine)

     以上代码完成SQLAlchemy的初始化和具体每个表的class定义。如果有多个表,就继续定义其他class,例如School:

    class School(Base):
    __tablename__ = 'school'
    id = ...
    name = ...

    create_engine()用来初始化数据库连接。SQLAlchemy用一个字符串表示连接信息:

    '数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'

    你只需要根据需要替换掉用户名、口令等信息即可。

    下面,我们看看如何向数据库表中添加一行记录。

    由于有了ORM,我们向数据库表中添加一行记录,可以视为添加一个User对象:

    # 创建session对象:
    session = DBSession()
    # 创建新User对象:
    new_user = User(id='5', name='Bob')
    # 添加到session:
    session.add(new_user)
    # 提交即保存到数据库:
    session.commit()
    # 关闭session:
    session.close()

    可见,关键是获取session,然后把对象添加到session,最后提交并关闭。DBSession对象可视为当前数据库连接。

    如何从数据库表中查询数据呢?有了ORM,查询出来的可以不再是tuple,而是User对象。SQLAlchemy提供的查询接口如下:

    # 创建Session:
    session = DBSession()
    # 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
    user = session.query(User).filter(User.id=='5').one()
    # 打印类型和对象的name属性:
    print('type:', type(user))
    print('name:', user.name)
    # 关闭Session:
    session.close()

    运行结果如下:

    type: <class '__main__.User'>
    name: Bob

    可见,ORM就是把数据库表的行与相应的对象建立关联,互相转换。

    由于关系数据库的多个表还可以用外键实现一对多、多对多等关联,相应地,ORM框架也可以提供两个对象之间的一对多、多对多等功能。

    例如,如果一个User拥有多个Book,就可以定义一对多关系如下:

    class User(Base):
    __tablename__ = 'user'

    id = Column(String(20), primary_key=True)
    name = Column(String(20))
    # 一对多:
    books = relationship('Book')

    class Book(Base):
    __tablename__ = 'book'

    id = Column(String(20), primary_key=True)
    name = Column(String(20))
    # “多”的一方的book表是通过外键关联到user表的:
    user_id = Column(String(20), ForeignKey('user.id'))

    当我们查询一个User对象时,该对象的books属性将返回一个包含若干个Book对象的list。

    示例一:

    from sqlalchemy import Column, String, create_engine, Table, MetaData
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.declarative import declarative_base

    # 链接数据库('数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名')
    engine = create_engine('mysql+mysqldb://root:mysql@localhost:3306/test',echo = True)
    Base = declarative_base() # 生成SQLORM基类


    class User(Base):
    __tablename__ = 'userinfo' # 表名

    id = Column(String(20), primary_key=True) # 字段
    name = Column(String(20)) # 字段


    # 创建userinfo表(所有表结构)
    Base.metadata.create_all(engine)
    DBSession = sessionmaker(bind=engine) # 创建与数据库的会话,返回的是一个类

     示例二:

    from sqlalchemy import create_engine, Column, Integer, String
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import sessionmaker


    engine = create_engine('mysql+pymysql://xiang:xiang@192.168.48.136/sqlalchemy') # 链接数据库
    DBsession = sessionmaker(bind=engine) # 创建与数据库的会话,返回的是一个类
    session = DBsession()

    Base = declarative_base() # 生成SQLORM基类

    class Student(Base):
    __tablename__ = 'student'
    id = Column(Integer, primary_key=True)
    name = Column(String(100))
    age = Column(Integer)
    address = Column(String(100))

    student1 = Student(id=1001, name='ling', age=25, address="beijing")
    student2 = Student(id=1002, name='molin', age=18, address="jiangxi")
    student3 = Student(id=1003, name='karl', age=16, address="suzhou")

    # session.add_all([student1, student2, student3])
    # session.commit()
    # session.close()

    a = session.query(Student).filter(Student.id>1001).all() #all指提取所有同名的,换成first的话指的是提取同名的第一个
    print(a)
    for i in a:
    print(i.id)
    print(i.name)
    print(i.age)
    print(i.address)

     

  • 相关阅读:
    LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)
    LeetCode 1041. Robot Bounded In Circle (困于环中的机器人)
    LeetCode 1037. Valid Boomerang (有效的回旋镖)
    LeetCode 1108. Defanging an IP Address (IP 地址无效化)
    LeetCode 704. Binary Search (二分查找)
    LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)
    LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
    LeetCode 817. Linked List Components (链表组件)
    LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)
    29. Divide Two Integers
  • 原文地址:https://www.cnblogs.com/Jweiqing/p/9026081.html
Copyright © 2011-2022 走看看