Python-day(十二)-ORM之sqlalchemy

一、ORM介绍

    orm英文全称object relational mapping,就是对象映射关系程序,简单来说我们了你python这种面向对象的程序来说一切皆对象,但是我们使用的数据库却都是关系型的,为了保证一致的使用习惯,通过orm将编程语言的对象模型和数据库的关系模型建立映射关系,这样我们在使用编程语言对数据库进行操作的时候可以zhi'jie直接使用编程语言的对象模型进行操作就可以了,而不用直接使用sql语言。
   

  ORM的优点:

        1、隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心,他使得我们的通用数据库交互变的简单易行,并且完全不用考虑该死的sql语句。快速开发,由此而来。
        2、ORM使我们构造固化数据结构变的简单易行。   

  ORM的缺点:

        1、无可避免的,自动化意味这映射和关联管理,代价是牺牲性能(早期,这是所有人不喜欢ORM人的共同点)。现在的各种ORM框架都在尝试使用各种方法来减轻这块(lazyload,cache),效果还是很显著的。

二、sqlalchemy安装

    在python中,最有名的ORM框架是SQLAlchemy。用户包括OpenStack\dropbox等知名公司或应用,主要用户列表http://www.sqlalchemy.org/organizations.html#openstack
    
   

 


 

    dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作,如:
    
    MySQL-Python
        mysql+mysqldb://<user>:<password>@<host>[:<port>]/<dbname>
       
    pymysql
        mysql+pymysql://<username>:<password>@<host>/<dbname>[?<options>]
       
    MySQL-Connector
        mysql+mysqlconnector://<user>:<password>@<host>[:<port>]/<dbname>
       
    cx_Oracle
        oracle+cx_oracle://user:pass@host:port/dbname[?key=value&key=value...]
       
    更多详见:http://docs.sqlalchemy.org/en/latest/dialects/index.html
    
    安装sqlalchemy
        pip3 install SQLAlchemy
        pip3 install pymysql #由于mysqldb依然不支持py3,所以这里我们用pymysql与sqlalchemy交互。

三、内部处理

    使用Engine/ConnectionPilling/Dialect进行数据库操作,Engine使用ConnectionPooling连接数据库,然后在通过Dialect执行SQl语句。

#!/usr/bin/env python
        # -*- coding:utf-8 -*-
        from sqlalchemy import create_engine
        
        engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/t1", max_overflow=5)
        
        # 执行SQL
        # cur = engine.execute(
        #     "INSERT INTO hosts (host, color_id) VALUES ('1.1.1.22', 3)"
        # )
        
        # 新插入行自增ID
        # cur.lastrowid
        
        # 执行SQL
        # cur = engine.execute(
        #     "INSERT INTO hosts (host, color_id) VALUES(%s, %s)",[('1.1.1.22', 3),('1.1.1.221', 3),]
        # )
        
        
        # 执行SQL
        # cur = engine.execute(
        #     "INSERT INTO hosts (host, color_id) VALUES (%(host)s, %(color_id)s)",
        #     host='1.1.1.99', color_id=3
        # )
        
        # 执行SQL
        # cur = engine.execute('select * from hosts')
        # 获取第一行数据
        # cur.fetchone()
        # 获取第n行数据
        # cur.fetchmany(3)
        # 获取所有数据
        # cur.fetchall()        

四、ORM功能使用

    使用ORM/Schema Type/SQL Expression Language/Engine/ConnectionPooling/Dialect所有组件对数据进行操作,根据类创建对象,对象转换成SQL,执行SQL。

4.1、创建表

        #!/usr/bin/env python
        from sqlalchemy.ext.declarative import declarative_base
        from sqlalchemy import Column,Integer,String,ForeignKey,UniqueConstraint,Index
        from sqlalchemy.orm import sessionmaker,relationship
        from sqlalchemy import create_engine
        
        engine= create_engine("mysql+pymysql://chenxin:cx123456@172.16.17.100:3306/chenxin",max_overflow=5)
        
        Base=declarative_base()
        
        #创建单表
        
        class Users(Base):
            __tablename__ = 'users'
            id = Column(Integer,primary_key=True)
            name=Column(String(32))
            extra =Column(String(16))
        
            __table_args__ = (
                UniqueConstraint('id','name',name='uix_id_name'),
                    Index('ix_id_name','name','extra'),
            )
        # #一对多
        class Favor(Base):
            __tablename__='favor'
            nid=Column(Integer,primary_key=True)
            caption = Column(String(50),default='red',unique=True)
        
        class Person(Base):
            __tablename__='preson'
            nid=Column(Integer,primary_key=True)
            name=Column(String(32),index=True,nullable=True)
            favor_id=Column(Integer,ForeignKey("favor.nid"))
        
        #多对多
        class Group(Base):
            __tablename__='group'
            id=Column(Integer,primary_key=True)
            name=Column(String(64),unique=True,nullable=False)
            port=Column(Integer,default=22)
        class Server(Base):
            __tablename__='server'
            id=Column(Integer,primary_key=True,autoincrement=True)
            hostname=Column(String(64),unique=True,nullable=False)
        
        class ServerToGroup(Base):
            __tablename__='servertogroup'
            nid=Column(Integer,primary_key=True,autoincrement=True)
            server_id=Column(Integer,ForeignKey('server.id'))
            group_id = Column(Integer,ForeignKey('group.id'))
        
        def init_db():
            Base.metadata.create_all(engine)
        
        def drop_db():
            Base.metadata.drop_all(engine)
        
        
        if __name__ == '__main__':
            # drop_db()
            init_db()    

4.2、操作表

4.2.1、表结构+数据库连接       

内容为:创建表+创建会话内容
  创建会话           

Session=sessionmaker(bind=engine)
session=Session()

4.2.2、增

obj=Users(name="chenxin",extra='nb')
session.add(obj) #增加一条
session.add_all([
Users(name='chenxin1',extra='nb1'),
Users(name='chenxin3',extra='nb3'),])#增加多条
session.commit()#提交

4.2.3、删

session.query(Users).filter(Users.id >2).delete()
session.commit()

4.2.4、改

session.query(Users).filter(Users.id >1).update({"name":"Cx"})#将id大于1的所有数据的name都改为Cx session.query(Users).filter(Users.id>1).update({Users.name:Users.name+"099"},synchronize_session=False)#将id大于1的所有数据的name都追加099字符
session.query(Users).filter(Users.id >1).update({"num":Users.num+1},synchronize_session='evaluate')
session.commit()   

4.2.5、查

ret=session.query(Users).all()#查询所有Users表的数据,以列表的形式返回,返回格式[id-name]
ret=session.query(Users.name,Users.extra).all()#查询指定字段的值,以元组的形式返回,每条数据是一个元组
ret=session.query(Users).filter_by(name='chenxin').all()#查询name是chenxin的数据,以列表的实现返回,返回格式[id-name]
ret=session.query(Users).filter_by(name='chenxin').first()#查询name=chenxin的数据
print(ret)

4.2.6、其他        

    条件

ret=session.query(Users).filter_by(name='chenxin').all() #查询条件是name=chenixn的数据
ret=session.query(Users).filter(Users.id>1,Users.extra=='nb2').all()#查询条件是id>1,extra=nb2的数据
ret = session.query(Users).filter(Users.id.between(1,3),Users.name =='Cx099').all()#查询条件是id在1到3的范围,name=Cx099的数据
ret=session.query(Users).filter(Users.id.in_([1,3,4])).all()#查询条件的id在1,3,4中的所有字段
ret=session.query(Users).filter(~Users.id.in_([1,3,4])).all()#查询条件的id不在1,3,4中的所有字段         ret=session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='chenxin'))).all()#
print(ret)                    

    通配符

ret=session.query(Users).filter(Users.name.like('Cx%')).all() #查找Cx开头的字段
ret=session.query(Users).filter(~Users.name.like('Cx%')).all()#查找排除Cx开头的字段                

    限制

ret=session.query(Users)[1:3] #排除1和3的id数据          

    排序

ret=session.query(Users).order_by(Users.id.desc()).all()#按照id排序,倒序排序,默认是正序排列             
ret=session.query(Users).order_by(Users.name.desc(),Users.id.asc()).all()
               

    分组

from sqlalchemy.sql import func
ret=session.query(Users).group_by(Users.extra).all()
ret=session.query(func.max(Users.id),func.sum(Users.id),func.min(Users.id)).group_by(Users.name).all()
ret=session.query(func.max(Users.id),func.sum(Users.id),func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >1).all()

    连表      

ret = session.query(Users, Favor).filter(Users.id == Favor.nid).all()
                
ret = session.query(Person).join(Favor).all()
                
ret = session.query(Person).join(Favor, isouter=True).all()

    组合

q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union(q2).all()
                
q1 = session.query(Users.name).filter(Users.id > 2)
q2 = session.query(Favor.caption).filter(Favor.nid < 2)
ret = q1.union_all(q2).all()

           

posted @ 2017-01-09 14:44  技术处理你  阅读(252)  评论(0编辑  收藏  举报