• sqlalchem表关联(一对多,一对一,多对多)


    简介:

    sqlalchemy是我们在python中经常使用的ORM组件,用来把python和数据库模型连接起来。

    让用的关系型数据库,ms_sql_server , mysql,mariadb都是关系型数据库,那么我们一定要处理数据库之间的关系。

    本文将探索使用sqlalchemy对数据库关系进行定义,并结合flask的开发,明确在flask-admin当中如何快速实现这种关系。

    一:多对一

    1.很多工人在一个班组,很多人拥有相同的学历。那么我们就要在工人这个页面单选所属班组,学历等级。

    2.模型定义:

    class Group(Base):
        __tablename__ = 'group'
        id = Column(Integer, primary_key=True)
        users = relationship("Users", back_populates="group")
        name = Column(String(32))
    
        def __str__(self):
            return self.name
    
    
    class Users(Base):
        __tablename__ = 'users'
        id = Column(Integer, primary_key=True)
        group_id = Column(Integer, ForeignKey('group.id'))
        group = relationship("Group", back_populates="users")
        name = Column(String(32))
    
        def __str__(self):
            return self.name
    View Code

    3.测试:

    在flask-admin当中管理Users表时,可以单选一个班组名称。

    在flask-admin当中管理Group表时,可以多选用户。但是候选用户时所有用户,如果某个用户已经有一个所属班组,那么更新操作会覆盖这个用户之前的所属班组。

    日常操作,一般时在用户页修改所属班组,极少在班组页面进行多选添加成员。而数据定义当中的Group.users,是方便进行双向连接,可以根据班组查询用户的。如果没有其它功能需要读取这个列表,那么可以取消这个定义。

    如果需要这个操作,那么可以考虑在flask-admin中使用自定义视图的方式,不在创建,编辑表单中显示这个字段。

    class Group_view(ModelView):
        form_excluded_columns = ('users',)
    admin.add_view(ModelView(Users, session, name='用户'))  #系统默认视图注册
    admin.add_view(Users_view(Users, session, name='用户')) #使用自定义视图注册。

    二:多对多

    1.每个班组都有工长,副工长。

    2.模型定义:

    group_duties = Table('group_duties', Base.metadata,
                         Column('group_id', Integer, ForeignKey('group.id')),
                         Column('duties_id', Integer, ForeignKey('duties.id'))
                         )
    
    
    class Group(Base):
        __tablename__ = 'group'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        duties = relationship("Duties", secondary=group_duties)
    
        def __str__(self):
            return self.name
    
    
    class Duties(Base):
        __tablename__ = 'duties'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        group = relationship("Group", secondary=group_duties)
    
        def __str__(self):
            return self.name
    
    
    class Duties_views(ModelView):
        form_excluded_columns = ('group',)
    View Code

     3.测试

    无论是班组表还是职务表,都可以进行多选。而且互相并不影响,但是实际使用中,一般是会对班组进行操作,对班组设置职务,而不是在职务选择班组,所以像多对一一样,我在表单隐藏了一项。

    4.删除

    当使用多对多关系时,我们同时使用了3张表,flask-admin只管理了两张表,第三张表作为中间表,当在flask-admin当中删除任意一项时,会自动处理中间表,删除中间表和该数据相关的条目。

    三:一对一

    1.我认为这个一对一是垂直分表来使用的东西。当数据口够大的时候,垂直分表,甚至分库,将是有效提升执行效率的办法。

    2.源码:

    class User(Base):
        __tablename__ = 'user'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        ext = relationship("User_ext", uselist=False, back_populates="user")
    
        def __str__(self):
            return self.name
    
    
    class User_ext(Base):
        __tablename__ = 'user_ext'
        id = Column(Integer, primary_key=True)
        name = Column(String(32))
        user_id = Column(Integer, ForeignKey('user.id'))
        user = relationship("User", back_populates="ext")
    
        def __str__(self):
            return self.name
    View Code

    3.实验:

    主表或扩展表,都可以进行单选,选择另一个表的内容,但是和前面介绍的一样,最后一次操作,覆盖前期数据。

    4.暂时真不知道怎么用,也不会实现垂直分表。继续查资料把。

    四:

    五:

    六:

    七:

    八:

    九:

    十:

  • 相关阅读:
    文本框设置只读,后台可获取
    div 在同一行的 CSS处理
    在标签中添加属性
    (转)如何使用SignalTap II觀察reg與wire值? (SOC) (Verilog) (Quartus II) (SignalTap II)
    (转)如何使用ModelSim對Megafunction或LPM作仿真? (SOC) (MegaCore) (ModelSim)
    (笔记)TSL235新型光感器件强烈推荐使用
    (转)如何增加SignalTap II能觀察的reg與wire數量? (SOC) (Quartus II) (SignalTap II)
    (转) 如何將10進位轉2進位? (C/C++) (C)
    (转)如何使用ModelSim作前仿真與後仿真? (SOC) (Quartus II) (ModelSim)
    (笔记)关于LM3S片内FLASH编程的一点建议
  • 原文地址:https://www.cnblogs.com/jackadam/p/9472274.html
Copyright © 2020-2023  润新知