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中我们使用什么做返回值,在查询时就返回什么

      

  • 相关阅读:
    1052 Linked List Sorting (25 分)
    1051 Pop Sequence (25 分)
    1050 String Subtraction (20 分)
    1049 Counting Ones (30 分)
    1048 Find Coins (25 分)
    1047 Student List for Course (25 分)
    1046 Shortest Distance (20 分)
    1045 Favorite Color Stripe (30 分)
    1044 Shopping in Mars (25 分)
    1055 The World's Richest (25 分)
  • 原文地址:https://www.cnblogs.com/python-way/p/5731290.html
Copyright © 2011-2022 走看看