You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何构建SQLAlchemy邻接列表查询实现Flask网络设备域模型关联

SQLAlchemy 查询方案针对你的Flask网络设备域归属模型

嘿,你已经把模型的关联逻辑理得很清晰了!先假设你的模型定义大概是这样的(如果和你的实际代码有出入,微调下关联字段就行):

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Domain(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    # 一对多关联子域
    subdomains = db.relationship('Subdomain', back_populates='domain')
    # 一对多关联设备
    devices = db.relationship('Device', back_populates='domain')

class Subdomain(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    # 子域归属单个域,按你说的"子域到域为一对一",如果是严格一个子域对应唯一域,可加 unique=True
    domain_id = db.Column(db.Integer, db.ForeignKey('domain.id'), nullable=False)
    domain = db.relationship('Domain', back_populates='subdomains')

class Device(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(50), nullable=False)
    ip_address = db.Column(db.String(15), nullable=False)
    domain_id = db.Column(db.Integer, db.ForeignKey('domain.id'), nullable=False)
    domain = db.relationship('Domain', back_populates='devices')

下面针对你的关联关系,给出常用的SQLAlchemy查询示例:

1. 获取指定域下的所有子域

比如查询名为mpls-core的域下所有子域:

# 方式1:通过域对象的关联属性直接获取
core_domain = Domain.query.filter_by(name='mpls-core').first()
if core_domain:
    core_subdomains = core_domain.subdomains
    for sub in core_subdomains:
        print(f"子域:{sub.name}")

# 方式2:通过Join查询,适合复杂过滤场景
core_subdomains = Subdomain.query.join(Domain).filter(Domain.name == 'mpls-core').all()

2. 获取指定域下的所有设备

同样以mpls-core域为例:

# 方式1:域对象关联查询
core_domain = Domain.query.filter_by(name='mpls-core').first()
if core_domain:
    core_devices = core_domain.devices
    for dev in core_devices:
        print(f"设备:{dev.name} - {dev.ip_address}")

# 方式2:Join查询
core_devices = Device.query.join(Domain).filter(Domain.name == 'mpls-core').all()

3. 通过子域反查所属的父域

比如查询名为edge-west的子域对应的父域:

subdomain = Subdomain.query.filter_by(name='edge-west').first()
if subdomain:
    parent_domain = subdomain.domain
    print(f"子域 {subdomain.name} 所属域:{parent_domain.name}")

4. 通过设备反查所属的域

比如查询名为pe-router-01的设备所属域:

device = Device.query.filter_by(name='pe-router-01').first()
if device:
    device_domain = device.domain
    print(f"设备 {device.name} 所属域:{device_domain.name}")

5. 复杂关联查询:获取某子域所属域下的所有设备

比如找到edge-west子域后,获取其所属域的全部设备:

# 方式1:分步查询,逻辑直观
subdomain = Subdomain.query.filter_by(name='edge-west').first()
if subdomain:
    domain_devices = subdomain.domain.devices
    for dev in domain_devices:
        print(f"{subdomain.domain.name} 域下设备:{dev.name}")

# 方式2:一次Join完成,性能更优
domain_devices = Device.query.join(Domain).join(Subdomain)\
    .filter(Subdomain.name == 'edge-west').all()

6. 带过滤条件的精准查询

比如查询mpls-core域下IP以192.168.1.开头的设备:

filtered_devices = Device.query.join(Domain)\
    .filter(Domain.name == 'mpls-core', Device.ip_address.like('192.168.1.%')).all()

7. 预加载关联数据(避免N+1查询问题)

如果需要一次性加载所有域、它们的子域和设备,避免多次查询数据库,用joinedload实现预加载:

from sqlalchemy.orm import joinedload

domains_with_relations = Domain.query.options(
    joinedload(Domain.subdomains),
    joinedload(Domain.devices)
).all()

for domain in domains_with_relations:
    print(f"\n=== 域:{domain.name} ===")
    print("子域列表:")
    for sub in domain.subdomains:
        print(f"  - {sub.name}")
    print("设备列表:")
    for dev in domain.devices:
        print(f"  - {dev.name} ({dev.ip_address})")

内容的提问来源于stack exchange,提问作者John Jensen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:29:19