zoukankan      html  css  js  c++  java
  • python_way day13 sqlalchemy

    sqlalchemy

    外键:分表后如果不做约束,与分表后不相符的值也可以插入,为了制约这种行为所以就出现了外键关联,一个字段外键关联到分表的那个字段后,必须输入那个字段中有的值

    一对多

    多对多

    sqlalchemy 中的方法:

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

    1、一对多

    复习时候做的例子

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint
    from sqlalchemy.orm import sessionmaker, relationships
    
    #数据库连接
    engine = create_engine("mysql+pymysql://root:123@192.168.56.5:3306/s13", max_overflow=5) #mysql需要授权本主机
    
    
    Base = declarative_base()
    
    
    class User(Base):
        __tablename__ = "user"  #表名叫User
        nid = Column(Integer, primary_key=True, autoincrement=True )  #Column表中的列的关键字 , Integer,整数, primary_key=True 主键, autoincrement=True自增
    username = Column(String(32)) #第二列为 名字 的一列
    group_id = Column(Integer, ForeignKey("group.nid")) #和 group的nid 建立外键,user和group的位置谁在上面都可以.
    class Group(Base):
    __tablename__
    = "group"
    nid
    = Column(Integer, primary_key=True, autoincrement=True)
    caption
    = Column(String(32))


    def init_db():
    #创建表
    Base.metadata.create_all(engine)


    def drop_db():
    #删除表
    Base.metadata.drop_all(engine)



    #init_db()
    Session = sessionmaker(bind=engine) #通过engine 的对象开始创建表中的内容
    session = Session()

    单条插入数据的方法
      #因为人在组中,人的外键是组,所以要先创建组中的数据,要不然就user就没法用组中的这些字段了
      session.add(Group(caption='dba'))
      session.add(Group(caption='yunwei'))
      session.add(Group(caption='jiankong'))
      session.commit()
     
    一、#创建表结构
    class Host(Base):  #所有的子类都继承这个基类
        #创建表结构
        __tablename__ = 'hosts'
        id = Column(Integer, primary_key=True,autoincrement=True)    #Colum 表中的列 , Integer,整数, primary_key=True 主键,  autoincrement=True自增
    hostname = Column(String(64),unique=True,nullable=False)
    group_id
    = Column(Integer,ForeignKey('groups.id')) #创建外面hosts中的group_id关联到work_group的id
    group = relationship("Group") #要写大写的实例名字通过映射的关系 , 能在hosts表中查询到外键表中的其他value
        def __repr__(self):
            return "<id = %s,jump_user_name=%s>" % (self.id, self.username)
     class Group(Base): __tablename__= 'groups' 
        id
    = Column(Integer,primary_key=True) #自动自增,主键  
        
    name = Column(String(64),unique=True,nullable=False)

    Base.metadata.create_all(engine)
    #执行上面的sql
    图示: group
    1 web 
     
    2 db host hostname   

      外键group_id
    1   nginx        1
    2   mysql       2

    这时候我们把host的group_id 和 group.id 做了外键关联
    意思就是说我必须有group组,在能创建host组,或者说我们也可以先把host的这是为可以为空,这样就可以先填写host这涨表了

    二、#插入数据
    第一种插入数据的方法
    1、我们可以直接插入host主机
    h1 = Host(hostname = "nginx")
    h2 = Host(hostname = "mysql")
    session.add_all([h1,h2])
    session.commit()
    2、然后我们再插入group数据

    g1 = Group(name = 'web')
    g2 = Group(name = 'db')

    session.add_all([g1,g2])
    session.commit()

    3、再做host和group关联(就是把host的group_id 改下)
    g1 = session.query(Group).filter(Group.name == "web").first()      #找出g1的对象
    h1 = session.query(Host).filter(Host.hostname=='nginx').update({"group_id":g1.id})
    session.commit()

    #插入数据时也可以以主动指定外键的值,但是不要超过被关联的键的范围就可以
    h1 = Host(hostname = "nginx",group_id = 1)
    h2 = Host(hostname = "mysql",group_id = 2)
    h3 = Host(hostname = "origer",group_id = 3)  这样就报错了



    第二种插入数据的方法
    先把group表值插进去,然后再插入host表
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()


    g1 = Group(name = 'web') #先插入group表
    g2 = Group(name = 'db')
    session.add_all([g1,g2])
    #
    gw = session.query(Group).filter(Group.name == 'web').first() #不用提交g1就可以在内存中查询到group中对应的数据,
    gb = session.query(Group).filter(Group.name == 'db').first()
    h1 = Host(hostname = "nginx",group_id = gw.id)            #直接复制给h1使用
    h2 = Host(hostname = "mysql",group_id = gb.id)
    session.add_all([h1,h2])
    session.commit()
    三、查询

    1、all 和 first
    all()
    gw = session.query(Group).all()
    print(gw)
    [<__main__.Group object at 0x0000003438C3F0F0>, <__main__.Group object at 0x0000003438C3F160>] #拿到了跟Group有关的所有数据,是个列表
    print(gw[0].name)   
    db
    print(gw[0].id)
    2

    first()
    gw = session.query(Group).first()
    print(gw)
    <__main__.Group object at 0x000000C703531208> #这个就是获取匹配到的第一个对象
    print(gw.name)
    db
    print(gw.id)
    2

    2、query()
    query中是要查的表,里面放的是表的类名,这里也是有2中情况

    query(class)
    gw = session.query(Group).all()
    print(gw)
    [<__main__.Group object at 0x000000446E0C1080>, <__main__.Group object at 0x000000446E0C10F0>] #这样知道的是所有的类对象,是个列表

    query(class.args)
    gw = session.query(Group.name).all()
    print(gw)
    [('db',), ('web',)]

    3、连表查询
    SessionCls = sessionmaker(bind=engine)
    session = SessionCls()


    a、join : inner join
    gw = session.query(Group).join(Host).all()
    print(gw)
    [<__main__.Group object at 0x0000002B1B345860>]
     
    b、isouter=True : lelf join 
    gw = session.query(Host).join(Group,isouter=True).all()
    print(gw)
    [hostanme : nginx  -  group_id = 1, hostanme : mysql  -  group_id = 1]

    +----+----------+----------+------+------+
    | id | hostname | group_id | id | name   |
    +----+----------+----------+------+------+
    | 1 | nginx    | 1     | 1   | web  |
    | 2 | mysql    | 1     | 1   | web  |
    +----+----------+----------+------+------+

    上图发现,我们获取到的只是host表里的内容,并没有group中的内容

     

      c、我如果我们想要把host表中和gorup中的内容都获取到

    gw = session.query(Host,Group).join(Group,isouter=True).all()
    print(gw)
    [(hostanme : nginx  -  group_id = 1, <__main__.Group object at 0x000000B3C53140B8>), (hostanme : mysql  -  group_id = 1, <__main__.Group object at 0x000000B3C53140B8>)]

    d、我们想要拿到准确的内容,不要对象怎么做?
    gw = session.query(Host.hostname,Group.name).join(Group,isouter=True).all()
    print(gw)
    [('nginx', 'web'), ('mysql', 'web')]

     使用join固然可以查到我们想要的东西,但是sqlalchemy又帮我们封装了一个很好用的东西

    relationship(“Class”)
    class Host(Base):  #所有的子类都继承这个基类
        #创建表结构
        __tablename__ = 'hosts'
        id = Column(Integer, primary_key=True,autoincrement=True) 
        hostname = Column(String(64),unique=True,nullable=False)     
        group_id = Column(Integer,ForeignKey('groups.id'))   #创建外面hosts中的group_id关联到work_group的id
        group = relationship("Group",backref="host")   #要写大写的实例名字通过映射的关系 , 能在hosts表中查询到外键表中的其他value
      #一般情况下foreignkey和relationship是在一起


    #通过Host正向查找主机名是nginx的外键关联的是那个组
    obj = session.query(Host).filter(Host.hostname == 'nginx').first()
    print(obj.group.name)

    #通过Group正向查找组名是web的都有哪些主机
    obj2 = session.query(Group).filter(Group.name == "web").first() 先找到的obj2是组为web的一样group主句
    #和obj2有关系的host中是有2台关联着group的web
    for h in obj2.host:
    print(h.hostname)

      nginx
      mysql

     


    自定义查询返回值:

    class JumpUser(Base):
        __tablename__ = 'jump_user'
        id = Column(Integer, primary_key=True, autoincrement=True)
        username = Column(Integer,unique=True,nullable=False)
        passwd = Column(Integer,nullable=False)
        groups = relationship("Group",secondary=lambda : JumpUser_2_Group.__table__,backref='jumpuser_list')
        host_list = relationship("HostUser", secondary=lambda: JumpUser_2_HostUser.__table__, backref='jumpuser_list')
        def __repr__(self):
            return "<id = %s,jump_user_name=%s>" % (self.id, self.username)

    repr中我们使用什么做返回值,在查询时就返回什么

      

  • 相关阅读:
    对拍
    浅谈trie树
    蒟蒻的二分模板
    浅谈线性素数筛
    浅谈树状数组
    HDU 2181 哈密顿绕行世界问题
    HDU 3567 Eight II
    HDU 1043 Eight
    POJ 3076 Sudoku
    hihoCoder 1087 Hamiltonian Cycle
  • 原文地址:https://www.cnblogs.com/python-way/p/5731290.html
Copyright © 2011-2022 走看看