zoukankan      html  css  js  c++  java
  • Python SQLAlchemy

    1.创建数据库

    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://root:Passw0rd!@192.168.2.101/beadata", max_overflow=5)
    
    Base = declarative_base()
    
    class Test(Base):
        __tablename__ = 'Test'
        nid = Column(Integer,primary_key=True,autoincrement=True)
        name = Column(String(32))
    
    class Group(Base):
        __tablename__ = 'Group'
        nid = Column(Integer,primary_key=True,autoincrement=True)
        caption = Column(String(32))
    
    class User(Base):
        __tablename__ = 'User'
        nid = Column(Integer,primary_key=True,autoincrement=True)
        username = Column(String(32))
        group_id = Column(Integer,ForeignKey('Group.nid'))
    
    def init_db():
        Base.metadata.create_all(engine)
    
    # def drop_db():
    #     Base.metadata.drop_all(engine)
    
    init_db()

    执行init_db创建一个数据库的对象(数据库必须存在),创建了上面的三张表。需要执行操作,要创建session

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

    然后利用session来增加数据:

    session.add(Group(caption='dba'))
    session.add(Group(caption='dvd'))
    
    
    session.add_all([
        User(username='alex4',group_id='4'),
        User(username='alex5',group_id='5'),
        User(username='alex6',group_id='6'),
    ])
    
    session.commit()

    插入的时候报键值对错误。

    2.单表查询,得到的结果是一个列表的对象

    ret = session.query(User).filter(User.username == 'alex1').all()
    print (ret)
    print (ret[0].nid,ret[0].username,ret[0].group_id)

    [<__main__.User object at 0x000000000375CA20>]
    1 alex1 1

    需要注意的是,我们的ret返回的时候其实是一个列表的对象,那么如何能返回我们看到的数据呢?在SQLAlchemy中,我们定义了__repr__的方法,重写__repr__方法后,每次返回的就不是对象而是看到的数据了。

    class User(Base):
        __tablename__ = 'User'
        nid = Column(Integer,primary_key=True,autoincrement=True)
        username = Column(String(32))
        group_id = Column(Integer,ForeignKey('Group.nid'))
    
        def __repr__(self):
            temp = "[%s --- %s --- %s]"%(self.nid,self.username,self.group_id)
            return temp

    返回结果:

    [[1 --- alex1 --- 1], [2 --- alex2 --- 2]]

    3.一对多之正向查找与反向查找

    我们设计两张表:

    Group表:

    nid caption
    1 dba
    2 dvd
    3 sic

     User表:

    nid username group_id
    1 alex1 1
    2 alex2 1
    15 alex1 2
    16 alex1 1

    在数据中,JOIN操作得到的结果如下:

    JOIN:
    sql = session.query(User).join(Group)
    print(sql)
    ret = session.query(User).join(Group).all()
    print (ret)
    结果:
    SELECT "User".nid AS "User_nid", "User".username AS "User_username", "User".group_id AS "User_group_id" 
    FROM "User" JOIN "Group" ON "Group".nid = "User".group_id
    [[1 --- alex1 --- 1], [2 --- alex2 --- 1], [15 --- alex1 --- 2], [16 --- alex1 --- 1]]

    User LEFT JOIN Group

    sql = session.query(User).join(Group,isouter=True)
    print(sql)
    ret = session.query(User).join(Group,isouter=True).all()
    print (ret)
    SELECT "User".nid AS "User_nid", "User".username AS "User_username", "User".group_id AS "User_group_id" 
    FROM "User" LEFT OUTER JOIN "Group" ON "Group".nid = "User".group_id
    [[1 --- alex1 --- 1], [2 --- alex2 --- 1], [15 --- alex1 --- 2], [16 --- alex1 --- 1]]

    Group LEFT JOIN User

    sql = session.query(Group,User.username).join(User,isouter=True)
    print(sql)
    ret = session.query(Group,User.username).join(User,isouter=True).all()
    print (ret)

    SELECT "Group".nid AS "Group_nid", "Group".caption AS "Group_caption", "User".username AS "User_username"
    FROM "Group" LEFT OUTER JOIN "User" ON "Group".nid = "User".group_id
    [([1 --- dba], 'alex1'), ([1 --- dba], 'alex2'), ([2 --- dvd], 'alex1'), ([3 --- sic], None)]

    正向查找:

      传统形式下,我们要查找用户'alex2'属于哪个组,需要执行下面的命令:

    ret = session.query(User.username,Group.caption).join(Group).filter(User.username == 'alex2').all()
    print (ret)

    执行结果:

    [('alex2', 'dba')]

    但在新方法下面:

    ret = session.query(User).filter(User.username == 'alex2').all()
    for obj in ret:
        print (obj.nid,obj.username,obj.group,obj.group.caption)

    执行结果:

    2 alex2 [1 --- dba] dba

    原因在于,在'User'表中有如下的定义

     group = relationship("Group", backref='uuu')

    表示的意思是在'User'表中隐性的添加了一列叫做'group',这一列表示的就是表中数据是属于'Group'中的那一个组的对应关系,它返回的是一个对象,因此可以使用obj.group.caption来访问'Group'中的数据。

    =================================================================================================

    反向查找:

      传统形式下,我们需要获取到'dba'这个角色的内容,需要执行下面的命令:

    ret = session.query(User.username,Group.caption).join(Group,isouter=True).filter(Group.caption == 'dba').all()
    print (ret)

    执行结果:

    [('alex1', 'dba'), ('alex2', 'dba'), ('alex1', 'dba')]

    但是在新方法下面:

    obj = session.query(Group).filter(Group.caption == 'dba').all()
    for item in obj:
        print (item.uuu)

    执行结果:

    [[1 --- alex1 --- 1], [2 --- alex2 --- 1], [16 --- alex1 --- 1]]

    原因在于,在于外键在同一个类的定义里面,有如下的说明:

    class User(Base):
        __tablename__ = 'User'
        nid = Column(Integer,primary_key=True,autoincrement=True)
        username = Column(String(32))
        group_id = Column(Integer,ForeignKey('Group.nid'))
        group = relationship("Group", backref='uuu')
    
        def __repr__(self):
            temp = "[%s --- %s --- %s]"%(self.nid,self.username,self.group_id)
            return temp

    这相当于定义了在User表中添加了一个字段为group,这个字段记录了用户对应的组,而'uuu'则相当于在表Group中每一行中添加了一个列表,内容是属于这个组的各个用户的数据。

  • 相关阅读:
    Merge into使用详解( 同时执行inserts和updates操作 )
    sql执行计划解析案例(二)
    包的定义和导入-----package
    jQuery练习实例(四)
    打印沙漏形
    Java的RandomAccessFile
    农场有头大母牛,每年生头小母牛,小母牛五年后生小母牛,问20年后农场一共有多少头牛?(用面向对象的思想)
    关于编译Lambda时报告返回的为void的错误
    银行对账
    mysql查询随机几条数据(速度快)
  • 原文地址:https://www.cnblogs.com/python-study/p/5889835.html
Copyright © 2011-2022 走看看