zoukankan      html  css  js  c++  java
  • day17-20180510笔记

    笔记:python的SQLAlchemy

    一、python的SQLAIchemy

    1、ORM
    ORM(Object Relational Mapping)框架采用元数据来描述对象一关系映射细节,元数据一般采用XML格式,并且存放在专门的对象一映射文件中。

    2、ORM的思想
    数据库中每次查出来的数据都用一个类表示,这个类的属性和数据库中表的字段一一对应。多条数据,就是一个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架构应用而生。

    3、SQLAIchemy
    Python中最有名的ORM架构就是SQLAlchemy,我们主要就是来学习SQLAlchemy的使用
    安装环境:
    pip install SQLAlchemy


    安装mysql
    yum install mysql-server mysql
    service mysqld restart
    sysctmctl restart mysql.service
    创建数据库
    create database sqlalchemy;
    授权:
    GRANT ALL PRIVILEGES ON *.* TO 'xiang'@'%' IDENTIFIED BY ‘xiang’;
    初始化连接:
    from sqlalchemy import create_engine
    engine = create_engine('mysql://xiang:xiang@192.168.48.131/sqlalchemy', echo=True)
    echo参数为True时,会显示每条执行的SQL语句,可以关闭,
    create_engine()返回一个Engine的实例,并且它表示通过数据库语法处理细节的核心接口,在这种情况下,数据库语法将会被解释成python的类方法。
    mysql://xiang:xiang@192.168.48.131/sqlalchemy
    mysql: 指定是哪种数据库连接
    第一个xiang: 用户名
    第二个xiang: xiang用户对应的密码
    192.168.48.131: 数据库的ip
    sqlalchemy: 数据库需要连接库的名字
    
    
    创建表格
    1. 主要是通过sql语句来创建表格:
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    
    sql = '''create table student(
        id int not null primary key,
        name varchar(50),
        age int,
        address varchar(100));
    '''
    
    
    engine = create_engine('mysql://xiang:xiang@192.168.48.131/sqlalchemy')
    conn = engine.connect()
    conn.execute(sql)
    engine.connect() 表示获取到数据库连接。类似我们在MySQLdb中游标course的作用。
    2. 通过ORM方式创建表格
    from sqlalchemy import Column
    from sqlalchemy import Integer
    from sqlalchemy import MetaData
    from sqlalchemy import String
    from sqlalchemy import Table
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    
    engine = create_engine('mysql://xiang:xiang@192.168.48.131/sqlalchemy')
    metadata = MetaData(engine)
    user = Table('user', metadata,
                 Column('id', Integer, primary_key=True),
                 Column('name', String(20)),
                 Column('fullname', String(40))
                 )
    metadata.create_all(engine)
    conn = engine.connect()
    print(conn)
    以上方式都可以创建数据库表
    MetaData类主要用于保存表结构,连接字符串等数据,是一个多表共享的对象
    metadata = MetaData(engine) 绑定一个数据源的metadata
    metadata.create_all(engine) 是来创建表,这个操作是安全的操作,会先判断表是否存在。
    Table类
    构造函数:
    Table.__init__(self, name, metadata,*args, **kwargs)
    name 表名
    metadata 共享的元数据
    *args Column 是列定义,详见下一节
    下面是可变参数 **kwargs 定义
    schema 此表的结构名称,默认None
    autoload 自动从现有表中读入表结构,默认False
    autoload_with 从其他engine读取结构,默认None


    include_columns 如果autoload设置为True,则此项数组中的列明将被引用,没有写的列明将被忽略,None表示所有都列明都引用,默认None
    mustexist 如果为True,表示这个表必须在其他的python应用中定义,必须是metadata的一部分,默认False
    useexisting 如果为True,表示这个表必须被其他应用定义过,将忽略结构定义,默认False
    owner 表所有者,用于Orcal,默认None
    quote 设置为True,如果表明是SQL关键字,将强制转义,默认False
    quote_schema 设置为True,如果列明是SQL关键字,将强制转义,默认False
    mysql_engine mysql专用,可以设置'InnoDB'或'MyISAM'

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time    : 2018/5/10 22:04
    # @Author  : lingxiangxiang
    # @File    : demon4.py
    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()
    
    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()
    print(a)
    for i in a:
        print(i.id)
        print(i.name)
        print(i.age)
        print(i.address)
    
    
    '''
    filter和filter_by
    filter_by(name="ling")  不能使用>  <  =
    filter(Student.id>1001)  这个就必须使用Student.id  可以使用> < =等
    '''
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Time    : 2018/5/10 22:17
    # @Author  : lingxiangxiang
    # @File    : demon5.py
    
    from sqlalchemy import create_engine
    from sqlalchemy.orm import sessionmaker
    
    from day17.demon4 import Student
    
    engine = create_engine('mysql+pymysql://xiang:xiang@192.168.48.136/sqlalchemy')
    DBsession = sessionmaker(bind=engine)
    session = DBsession()
    
    #session.query(Student)

    数据库表是一个二维表,包含多行多列。把一个表的内容用Python的数据结构表示出来的话,可以用一个list表示多行,list的每一个元素是tuple,表示一行记录,比如,包含idnameuser表:

    [
        ('1', 'Michael'),
        ('2', 'Bob'),
        ('3', 'Adam')
    ]

    Python的DB-API返回的数据结构就是像上面这样表示的。

    但是用tuple表示一行很难看出表的结构。如果把一个tuple用class实例来表示,就可以更容易地看出表的结构来:

    class User(object):
        def __init__(self, id, name):
            self.id = id
            self.name = name
    
    [
        User('1', 'Michael'),
        User('2', 'Bob'),
        User('3', 'Adam')
    ]

    在Python中,最有名的ORM框架是SQLAlchemy。我们来看看SQLAlchemy的用法。

    首先通过pip安装SQLAlchemy:

    $ pip install sqlalchemy

    然后,利用上次我们在MySQL的test数据库中创建的user表,用SQLAlchemy来试试:

    第一步,导入SQLAlchemy,并初始化DBSession:

    # 导入:
    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。

    小结

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

    正确使用ORM的前提是了解关系数据库的原理。




    参考源码:
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    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)
    
    # 创建session对象:
    session = DBSession()
    # 创建新User对象:
    new_user = User(id='5', name='Bob')
    # 添加到session:
    session.add(new_user)
    # 提交即保存到数据库:
    session.commit()
    # 关闭session:
    session.close()
    
    # 创建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()





  • 相关阅读:
    正则表达式
    网络编程
    多线程
    IO—Data
    IO-对象流
    IO-转换流
    异常
    常用类——File——Random——Math——枚举
    每月博客-20180310
    每月博客-20180204
  • 原文地址:https://www.cnblogs.com/ivan-yang/p/9025218.html
Copyright © 2011-2022 走看看