zoukankan      html  css  js  c++  java
  • python之sqlalchemy

    python之sqlalchemy

                                                         

    ORM:

    ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。 正确使用ORM的前提是了解关系数据库的原理。 ORM就是把数据库表的行与相应的对象建立关联,互相转换。 由于关系数据库的多个表还可以用外键实现一对多、多对多等关联,相应地, ORM框架也可以提供两个对象之间的一对多、多对多等功能。

    一 单表操作(不涉及一对多,多对多)
    复制代码
    #coding:utf8
    import sqlalchemy
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String
    from sqlalchemy.orm import sessionmaker
    print(sqlalchemy.__version__)
    
    
    engine = create_engine('sqlite:///dbyuan1.db', echo=True)
    
    Base = declarative_base()#生成一个SQLORM基类
    
    class User(Base):
        __tablename__ = 'users'
    
        id = Column(Integer, primary_key=True)
        name = Column(String)
        fullname = Column(String)
        password = Column(String)
    
        def __repr__(self):
           return "<User(name='%s', fullname='%s', password='%s')>" % (
                                self.name, self.fullname, self.password)
    
    Base.metadata.create_all(engine)  #创建所有表结构
    
    ed_user = User(name='xiaoyu', fullname='Xiaoyu Liu', password='123')
    print(ed_user)
    #这两行触发sessionmaker类下的__call__方法,return得到 Session实例,赋给变量session,所以session可以调用Session类下的add,add_all等方法
    MySession = sessionmaker(bind=engine)
    session = MySession()
    
    session.add(ed_user)
    # our_user = session.query(User).filter_by(name='ed').first()
    # SELECT * FROM users WHERE name="ed" LIMIT 1;
    # session.add_all([
    #     User(name='alex', fullname='Alex Li', password='456'),
    #     User(name='alex', fullname='Alex old', password='789'),
    #     User(name='peiqi', fullname='Peiqi Wu', password='sxsxsx')])
    
    session.commit()
    
    #print(">>>",session.query(User).filter_by(name='ed').first())
    #print(session.query(User).all())
    # for row in session.query(User).order_by(User.id):
    #      print(row)
    # for row in session.query(User).filter(User.name.in_(['alex', 'wendy', 'jack'])):#这里的名字是完全匹配
    #     print(row)
    # for row in session.query(User).filter(~User.name.in_(['ed', 'wendy', 'jack'])):
    #     print(row)
    #print(session.query(User).filter(User.name == 'ed').count())
    #from sqlalchemy import and_, or_
    
    # for row in session.query(User).filter(and_(User.name == 'ed', User.fullname == 'Ed Jones')):
    #     print(row)
    # for row in session.query(User).filter(or_(User.name == 'ed', User.name == 'wendy')):
    #     print(row)
    复制代码

      

     二  一对多的关联表操作

    实例1:

    复制代码
    #coding:utf8
    
    import sqlalchemy
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String,ForeignKey
    from sqlalchemy.orm import sessionmaker,relationship
    
    
    engine = create_engine('sqlite:///dbyuan2.db', echo=True)
    
    Base = declarative_base()
    
    class Father(Base):
        __tablename__ = 'father'
    #id = Column(Integer, primary_key=True)里的数据类型一定写整型(Integer)
        id = Column(Integer, primary_key=True)
        name = Column(String(20))
        def __repr__(self):
             return "<Father(name='%s')>" % self.name
    
    
    class Son(Base):
        __tablename__ = 'son'
    
        id = Column(Integer, primary_key=True)
        name = Column(String(20))
        #ForeignKey建在多的一方
        father_id = Column(String(20), ForeignKey('father.id'))
        father=relationship("Father",backref="son", order_by=id)
        def __repr__(self):
             return "<Son(name='%s')>" % self.name
    
    Base.metadata.create_all(engine)
    
    Session = sessionmaker(bind=engine)
    session = Session()
    
    
    f1= Father(name='zhangsan')
    f2= Father(name='lisi')
    f3= Father(name='wangwu')
    
    f1.son = [Son(name='zhangdasan'),Son(name='zhangersan')]
    
    
    session.add(f1)
    session.commit()
    
    for u, a in session.query(Father, Son).
                        filter(Father.id==Son.id).
                        all():
        print u, a   #<Father(name='zhangsan')> <Son(name='zhangdasan')>
    复制代码

       

       

    实例2:

    复制代码
    #__ *__ coding:utf8__*__
    
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String,and_,or_,ForeignKey
    from  sqlalchemy.orm import sessionmaker,relationship
    
    Base = declarative_base() #生成一个SqlORM 基类
    
    
    engine = create_engine('sqlite:///dbyuan3.db', echo=True)
    
    
    class Host(Base):
        __tablename__ ='host'
        id = Column(Integer,primary_key=True,autoincrement=True)
        hostname = Column(String(64),unique=True,nullable=False)
        ip_addr = Column(String(128),unique=True,nullable=False)
        port = Column(Integer,default=22)
        #前提 一个主机只能属于一个组
        group_id=Column(Integer,ForeignKey('group.id'))
        group=relationship('Group',backref='host')
        def __repr__(self):
            return "id:%s hostname:%s port:%s"%(self.id,self.hostname,self.port)
    
    
    class Group(Base):
        __tablename__='group'
        id=Column(Integer,primary_key=True)
        name=Column(String(64),unique=True,nullable=False)
    
        def __repr__(self):
            return "id:%s hostname:%s"%(self.id,self.name)
    
    
    Base.metadata.create_all(engine) #创建所有表结构
    
    if __name__ == '__main__':
        SessionCls = sessionmaker(bind=engine,autoflush=False)
        session = SessionCls()
    
        g1=Group(name='g1')
        g2=Group(name='g2')
        g3=Group(name='g3')
        session.add_all([g1,g2,g3])
        session.commit()
    
        h1 = Host(hostname='localhost',ip_addr='127.0.0.1',group_id=g1.id)#g1如果在这之前没有提交,group_id拿到的永远是一个空值
        h2 = Host(hostname='ubuntu',ip_addr='192.168.2.243',port=20000)
        session.add_all([h1,h2])
    
        session.commit()
    
        g1=session.query(Group).filter(Group.name=='g1').first()
        h=session.query(Host).filter(Host.hostname=='localhost').first()#注意要加上first(),否则报错,注意与all()结果的不同
    
        print "<<<",g2
        print ">>>",h
    
        print(h.group.name)
        print g1.host
        print g1.host[0].hostname
    
        #g2.host什么结果?(未绑定,无结果)
    复制代码

       

       

    三 多对多的关联表操作

    复制代码
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    from sqlalchemy import create_engine,and_,or_,func,Table
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String,ForeignKey
    from  sqlalchemy.orm import sessionmaker,relationship
    
    Base = declarative_base() #生成一个SqlORM 基类
    
    
    Host2Group = Table('host_2_group',Base.metadata,
        Column('host_id',ForeignKey('host.id'),primary_key=True),
        Column('group_id',ForeignKey('group.id'),primary_key=True),)
    
    
    engine = create_engine('sqlite:///dbyuan4.db', echo=True)
    
    class Host(Base):
        __tablename__ = 'host'
    
        id = Column(Integer,primary_key=True,autoincrement=True)
        hostname = Column(String(64),unique=True,nullable=False)
        ip_addr = Column(String(128),unique=True,nullable=False)
        port = Column(Integer,default=22)
        group = relationship('Group',
                              secondary=Host2Group,
                              backref='host_list')
    
        #group =relationship("Group",back_populates='host_list')
        def __repr__(self):
            return  "<id=%s,hostname=%s, ip_addr=%s>" %(self.id,
                                                        self.hostname,
                                                        self.ip_addr)
    class Group(Base):
        __tablename__ = 'group'
        id = Column(Integer,primary_key=True)
        name = Column(String(64),unique=True,nullable=False)
    
        def __repr__(self):
            return  "<id=%s,name=%s>" %(self.id,self.name)
    
    Base.metadata.create_all(engine) #创建所有表结构
    
    if __name__ == '__main__':
        SessionCls = sessionmaker(bind=engine,autoflush=False)
        session = SessionCls()
    
    
        g1 = Group(name='g1')
        g2 = Group(name='g2')
        g3 = Group(name='g3')
        g4 = Group(name='g4')
        session.add_all([g1,g2,g3,g4])
        session.commit()
    
    
        #g4 = session.query(Group).filter(Group.name=='g4').first()
        #h = session.query(Host).filter(Host.hostname=='localhost').update({'group_id':g4.id})
        #h = session.query(Host).filter(Host.hostname=='localhost').first()
        #print("h1:",h.group.name )
        #print("g:",g4.host_list )
    
    
        h1 = Host(hostname='h1',ip_addr='192.168.1.56')
        h2 = Host(hostname='h2',ip_addr='192.168.1.57',port=10000)
        h3 = Host(hostname='ubuntu',ip_addr='192.168.1.58',port=10000)
        session.add_all([h1,h2,h3])
        session.commit()
    
        groups = session.query(Group).all()
        g1 = session.query(Group).first()
    
        h2 = session.query(Host).filter(Host.hostname=='h2').first()
        h2.group = groups[1:-1]
        print("===========>",h2.group)
    
        #objs = #session.query(Host).join(Host.group).group_by(Group.name).all()
        #objs = session.query(Host,func.count(Group.name)).
        #join(Host.group).group_by(Group.name).all()
        #print("-->objs:",objs)
        #print("++>",obj)
        #obj.hostname = "test server"
        #session.delete(obj)
        #objs = session.query(Host).filter(and_(Host.hostname.like("ub%"), Host.port > 20)).all()
    
        session.commit()
    复制代码

        

          

          

    注意:

          1   Session = sessionmaker(bind=engine,autoflush=False) 

          2   session.add添加数据到数据后,一定要session.commit()后才能增删改查,否则结果只能为none

          3   session.query(Group).filter(Group.name=='g1').first() 注意有无first()的区别

    再注意:

           1   关于 session.add   session.query   session.commit的顺序问题?

    就是说在同一个会话中, insert into table (xxxx)后,可以select * from xxx;可以查询到插入的数据,只是不能在其他会话,比如我另开一个客户端去连接数据库不能查询到刚刚插入的数据。

    这个数据已经到数据库。值是数据库吧这个数据给锁了。只有插入数据的那个session可以查看到,其他的session不能查看到,可以理解提交并解锁吧。

          2  第三张表必须利用table创建吗?NO

          3   联合唯一

          4   一对多的第二个例子,如何理解去掉第一个commit后就报错的现象

  • 相关阅读:
    冒泡排序法
    冒泡排序法
    【HAOI2008】圆上的整点
    2018年全国多校算法寒假训练营练习比赛(第四场)F:Call to your teacher
    (java)Jsoup爬虫学习--获取网页所有的图片,链接和其他信息,并检查url和文本信息
    CSS 选择器
    (java)selenium webdriver学习---实现简单的翻页,将页面内容的标题和标题链接取出
    (java)selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待
    使用D3绘制图表(5)--水平柱状图表
    使用D3绘制图表(4)--面积图表
  • 原文地址:https://www.cnblogs.com/guisheng/p/6036447.html
Copyright © 2011-2022 走看看