嵌套连接和别名(Flask-)SQLAlchemy

时间:2015-11-04 09:58:09

标签: python join sqlalchemy flask-sqlalchemy

我正在尝试从使用原始SQL切换到SQLAlchemy / Flask-SQLAlchemy。据我学习简单查询,我无法理解如何使用子查询,嵌套连接和别名。

现在我有我的SQL查询:

SELECT device.*, wifi.name as room FROM
(SELECT * FROM devices WHERE mac="{0}") as device
LEFT JOIN
    (SELECT w2.*, wifi_map.name as name FROM
        (SELECT * FROM (SELECT * FROM wifi ORDER BY signal_pow DESC) as w1 GROUP BY device_id) as w2
        INNER JOIN wifi_map
        ON w2.bssid=wifi_map.bssid)
    as wifi
ON device.id=wifi.device_id

我设法将LEFT JOIN部分转换为SQLAlchemy(别名为wifi的部分)。它看起来像这样:

sorted_wifi = db.session.query(WiFi).order_by(WiFi.signal_pow.desc())\
    .join(WiFi.map).subquery()
wifi_with_room = db.session.query().add_entity(WiFi, alias=sorted_wifi)\
    .group_by('device_id')

因此,此处wifi_with_room是包含模型WifiWiFi.map的行列表,作为匹配的模型列表WiFiMap(基于WiFi.bssid == WiFiMap.bssid)。但我不知道我应该如何与wifi_with_room一起加入Device。我试过了

db.session.query(Device).outerjoin(wifi_with_room)

但这给了我错误

  

每个派生表都必须有自己的别名

然后我尝试了

db.session.query(Device).outerjoin(wifi_with_room.alias('wifi'))

但它返回了

  

AttributeError:'Query'对象没有属性'alias'

我想要实现的是具有以下内容的行列表:

  • 模型Device(及其所有元素)
  • 通过匹配Device.room然后WiFiMap.nameWiFi.device_id == Device.id返回的WiFiMap.bssid == WiFi.bssid房间名称中的

以下是我的模特:

class Device(db.Model):
    __tablename__ = 'devices'

    id = db.Column(db.Integer, primary_key=True)
    mac = db.Column(db.Text)
    vendor = db.Column(db.Text)
    model = db.Column(db.Text)
    name = db.Column(db.Text)
    resolution_h = db.Column(db.Integer)
    resolution_w = db.Column(db.Integer)
    system_version = db.Column(db.Text)
    cpu_model = db.Column(db.Text)
    gpu = db.Column(db.Text)
    gpu_clock = db.Column(db.Integer)
    ram = db.Column(db.Integer)
    layouts = db.Column(db.Text)
    screen_size = db.Column(db.Float)
    screen_density = db.Column(db.Integer)
    imei = db.Column(db.Integer)
    density_cat = db.Column(db.Text)
    graphics_cat = db.Column(db.Text)
    type = db.Column(db.Text)
    last_active = db.Column(db.DateTime, onupdate=datetime.datetime.now)
    unavailable = db.Column(db.Integer)

class WiFi(db.Model):
    __tablename__ = 'wifi'

    id = db.Column(db.Integer, primary_key=True)
    device_id = db.Column(db.Integer, db.ForeignKey('devices.id', onupdate="CASCADE", ondelete="CASCADE"), index=True)
    bssid = db.Column(db.String(17), index=True)
    ssid = db.Column(db.Text)
    signal_pow = db.Column(db.Integer)

class WiFiMap(db.Model):
    __tablename__ = 'wifi_map'

    room = db.Column(db.Integer)
    x = db.Column(db.Integer)
    y = db.Column(db.Integer)
    bssid = db.Column(db.String(17), db.ForeignKey('wifi.bssid'), primary_key=True)
    ssid = db.Column(db.Text)
    name = db.Column(db.Text)
    wifi = db.relationship('WiFi', backref='map', lazy='immediate')

0 个答案:

没有答案