0

次の構造のMySQLデータベースがあり、誰かが以下のSQLクエリをSQLAlchemyに変換するのを手伝ってくれることを望んでいました.

データベース構造:

**bottom:**
id
name
middle_id

**middle:**
id
name
top_id

**top:**
id
name

ここに私のモデルがあります:

class Bottom(db.Model):
    id        = db.Column(db.Integer, primary_key=True)
    name      = db.Column(db.String(64))
    middle_id = db.Column(db.Integer, db.ForeignKey('middle.id'))
    middle    = db.relationship('Middle',
        backref=db.backref('bottoms', lazy='dynamic'))

class Middle(db.Model):
    id        = db.Column(db.Integer, primary_key=True)
    name      = db.Column(db.String(64))
    top_id    = db.Column(db.Integer, db.ForeignKey('top.id'))
    top       = db.relationship('Top',
        backref=db.backref('middles', lazy='dynamic'))

class Top(db.Model):
    id        = db.Column(db.Integer, primary_key=True)
    name      = db.Column(db.String(64))

SQLAlchemy に変換したい SQL は次のとおりです。

SELECT
  b.*,
  m.*,
  t.*
FROM bottom AS b
  LEFT JOIN (SELECT id, name, top_id  from middle) AS m  on m.id = b.middle_id
  LEFT JOIN (SELECT id, name FROM top) AS t   on t.id = m.top_id
WHERE b.name LIKE '%query%' OR m.name LIKE '%query%' OR t.name LIKE '%query%'

テーブルの下部の各エントリはmiddleに関連し、中央の各エントリはtopに関連しています。データベースにクエリを実行して、名前が LIKE %query% であるのすべてのエントリと、ミドルネームが LIKE %query% である下のすべてのエントリのエントリ、および中央が上である下のすべてのエントリのエントリを検索したい名前は LIKEクエリです。

次のようなSQLAlchemyに変換したい:

    return db.session.query(Bottom).filter( or_(Bottom.name.like('%query%'),
                                     Bottom.middle.name.like('%query%'),
                                     Bottom.middle.top.name.like('%query%'))
                                     )).all()

つまり、Middle のエントリに関連する Bottom のエントリがあり、Middle のエントリが Top のエントリに関連している場合、Top で適切な名前を検索すると、Middle のエントリではなく、そのエントリが返されます。は関連していますが、関連する Middle エントリに関連する Bottom エントリです。

以下に例を示します。

データ:

**bottom**
id        1
name      "Gus Fring"
middle_id 1

**middle**
id        1
name      "Jesse Pinkman"
top_id    1

**top**
id        1
name      "Walter White"

「Walter White」を検索すると、Middle リレーション (Jesse Pinkman) ではなく、Bottom リレーションから Middle リレーションの結果 (Gus Fring) が返されます。

前もって感謝します :)。

4

1 に答える 1

1
name_filter = '%query%'
qry = (session.query(Bottom).
        outerjoin(Middle).
        outerjoin(Top).
        filter(or_(
            Bottom.name.like(name_filter),
            Middle.name.like(name_filter),
            Top.name.like(name_filter),
            ))
        )

このクエリの実行の結果として、Bottom のインスタンスのみが取得されます。3 つすべてをタプル (Bottom、Middle、Top) として本当に必要な場合は、そのquery(...)部分を次のように置き換えます。session.query(Bottom, Middle, Top).

于 2012-07-02T12:09:38.280 に答える