Django ORMのGROUP_CONCAT


Django ORMの集約関数はクールです。 この状況が、別の=)を追加する理由でした

次に、mysql固有の関数について説明します。 GROUP_CONCAT GROUP_CONCAT魔法のピンクのポニー(ジャンゴトランクの写真のように)


興味のある機能は、2つのモジュールdjango.db.models.aggregatesdjango.db.models.sql.aggregatesます。 したがって、シーンはmodels.pyです。

  django.dbインポートモデルから
 ##集約関数##
 django.db.models.aggregatesからimport Aggregate#定義
 django.db.models.sql.aggregatesからSQLAggregate#実装としてAggregateをインポート 


最も興味深いものから始めましょう-実際の実装です。

 クラスSQLConcat(SQLAggregate):
     sql_function = "GROUP_CONCAT"
    
     def __init __(self、col、separator = '、'、** extra):
         self.sql_template = "%%(関数)s(%%(フィールド)s SEPARATOR '%s')"%セパレーター
         super(SQLConcat、self).__ init __(col、source = models.DecimalField()、** extra) 


(少なくとも)one models.DecimalField() 1つありますmodels.DecimalField()を親のコンストラクタに渡すことです。 これは、関数の処理結果が誤って数値型(!)に変換されないようにするために必要です。 このコードは、次にDjangoトランクを更新するかどうかで壊れます。Djangoトランクの次の更新後に表示されます。 あなたは警告されました。

実装の準備ができました。関数の退屈な定義に移りましょう。

 クラスConcat(集合):
     name = "Concat"
    
     def add_to_query(self、query、alias、col、source、is_summary):
        集計= SQLConcat(col、is_summary = is_summary、** self.extra)
         query.aggregates [エイリアス] =集計 


私たちの仕事が機能することを確認することは残っています:

  >>> Post.threads.aggregate(連結( 'id'))

 {'id__concat': '1,2,3,4'}

 >>> django.dbインポート接続から
 >>> connection.queries

 [{'sql':u "SELECT GROUP_CONCAT(` main_post`.`id` SEPARATOR '、')AS `id__concat` FROM` main_post`"、
   'time': '0.000'}] 


Habréの最初の投稿、uiii!

Source: https://habr.com/ru/post/J87096/


All Articles