不使用外键实现 Flask-SQLAlchemy 中多表链接查询

# -*- coding: utf-8 -*-
from sqlalchemy import Column, Integer, Float, JSON, DATE, Text, ForeignKey
from sqlalchemy.ext.declarative import declarative_base

# 创建基础的元数据
base_one = declarative_base()

class AnalysisModule(base_one):
    """
    模型,将映射到数据库表中
    """
    __tablename__ = 'analysis_module'

    # 主键ID
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 模块id
    module_key = Column(Text, nullable=False)
    # 模块名称
    module_name = Column(Text, nullable=False)
    # 功能id
    function_key = Column(Text, nullable=False)
    # 功能名称
    function_name = Column(Text, nullable=False)
    # 备注
    bz = Column(Text, nullable=False)
    # 状态
    state = Column(Integer, nullable=False)

    def __iter__(self):
        return self


class AnalysisModuleAlgorithmRelation(base_one):
    """
    模型,将映射到数据库表中
    """
    __tablename__ = 'analysis_module_algorithm_relation'

    # 主键ID
    id = Column(Integer, primary_key=True, autoincrement=True)
    # 功能id
    function_key = Column(Text, nullable=False)
    # 功能名称
    algorithm_key = Column(Text, nullable=False)
    # 状态
    use_state = Column(Integer, nullable=False)

    def __iter__(self):
        return self

def class_to_dict(obj):
    '''把对象(支持单个对象、list、set)转换成字典'''
    is_list = obj.__class__ == [].__class__
    is_set = obj.__class__ == set().__class__

    if is_list or is_set:
        obj_arr = []
        for o in obj:
            # 把Object对象转换成Dict对象
            dict = {}
            dict.update(o.__dict__)
            obj_arr.append(dict)
        return obj_arr
    else:
        dict = {}
        dict.update(obj.__dict__)
        dict.pop('_sa_instance_state', None)
        return dict

from server.dbs.db import session_zs
from sqlalchemy import text

with session_zs() as session:
    #单表,指定字段查询
    for row in session.query(AnalysisModule.module_key ,AnalysisModule.module_name).all():
        print(row)
        print(row.module_key, row.module_name)
    #单表,sql查询
    for row in session.query(AnalysisModule).from_statement(text("SELECT * FROM analysis_module where module_key=:module_key")).params(module_key='01').all():
        print(row)
        print(row.module_key, row.module_name)
    # 子查询关联查询
    stmt = session.query(AnalysisModuleAlgorithmRelation).filter(AnalysisModuleAlgorithmRelation.use_state==1).subquery()
    for u, count in session.query(AnalysisModule, stmt.c.algorithm_key).outerjoin(stmt, AnalysisModule.function_key == stmt.c.function_key):
        print(u)
        print(u.function_key, count)
    #单表简单查询
    stu_obj = session.query(AnalysisModule).filter(AnalysisModule.module_key=="01").all()
    for s in stu_obj:
        print(s.module_key, s.module_name)
        print(class_to_dict(s))
    # 关联查询,直接加条件
    stu_obj = session.query(AnalysisModule,AnalysisModuleAlgorithmRelation).filter(AnalysisModule.module_key=="01").filter(AnalysisModuleAlgorithmRelation.use_state==1).filter(AnalysisModule.function_key == AnalysisModuleAlgorithmRelation.function_key).all()
    for s in stu_obj:
        print(s)
        print({**class_to_dict(s[0]), **class_to_dict(s[1])})

    #关联查询 筛选字段 它是一个 AbstractKeyedTuple 对象,拥有一个 keys() 方法,这样可以很容易将其转换成 dict
    stu_obj = session.query(AnalysisModule.module_name, AnalysisModule.function_name, AnalysisModuleAlgorithmRelation.algorithm_key).join(AnalysisModuleAlgorithmRelation, AnalysisModule.function_key == AnalysisModuleAlgorithmRelation.function_key).filter(
        AnalysisModule.module_key == "01").filter(AnalysisModuleAlgorithmRelation.use_state == 1).all()
    for s in stu_obj:
        print(s)
        print(s.keys())
        print([dict(zip(s.keys(), s))])

    #关联查询 获得多个 Model 的记录
    stu_obj = session.query(AnalysisModule, AnalysisModuleAlgorithmRelation).join(AnalysisModuleAlgorithmRelation, AnalysisModule.function_key == AnalysisModuleAlgorithmRelation.function_key).filter(
        AnalysisModule.module_key == "01").filter(AnalysisModuleAlgorithmRelation.use_state == 1).all()
    for s in stu_obj:
        print(s)
        print({**class_to_dict(s[0]), **class_to_dict(s[1])})
    #关联查询 筛选字段 它是一个 AbstractKeyedTuple 对象,拥有一个 keys() 方法,这样可以很容易将其转换成 dict
    stu_obj = session.query(AnalysisModule, AnalysisModuleAlgorithmRelation).join(AnalysisModuleAlgorithmRelation, AnalysisModule.function_key == AnalysisModuleAlgorithmRelation.function_key).filter(
        AnalysisModule.module_key == "01").filter(AnalysisModuleAlgorithmRelation.use_state == 1).with_entities(AnalysisModule.module_name, AnalysisModule.function_name, AnalysisModuleAlgorithmRelation.algorithm_key).all()
    for s in stu_obj:
        print(s)
        print([dict(zip(s.keys(), s))])

参考:
https://www.cnblogs.com/shengs/p/10473524.html
https://blog.csdn.net/qq_43355223/article/details/83542739

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 Flask-SQLAlchemy 创建间表类时,建议采用以下命名规则: 1. 表名:采用复数形式,表示这是一个多对多的关系表。例如,如果你有两个类 `User` 和 `Role`,则它们之间的关系可以用一个间表来表示,该间表的表名应该为 `users_roles`。 2. 类名:采用单数形式,表示这是一个间表类。例如,如果你有一个间表 `users_roles`,则对应的类名应该为 `UserRole`。 3. 属性名:一般采用外键表名+外键字段名的形式。例如,如果你的间表 `users_roles` 包含外键 `user_id` 和 `role_id`,则对应的属性名应该为 `user_id` 和 `role_id`。 综上所述,你可以按照上述规则来命名你的间表类,例如: ```python from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64)) roles = db.relationship('Role', secondary='users_roles', backref=db.backref('users', lazy='dynamic')) class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64)) class UserRole(db.Model): __tablename__ = 'users_roles' user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True) role_id = db.Column(db.Integer, db.ForeignKey('roles.id'), primary_key=True) ``` 注意,这里的间表类 `UserRole` 包含了两个外键属性 `user_id` 和 `role_id`,分别对应于 `users_roles` 表外键 `user_id` 和 `role_id`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值