2016-05-25 2 views
1

現在、SQLAlchemyのORMクエリの一部のテーブルでTABLESAMPLEにアクセスできますか?SQLAlchemyでTABLESAMPLEする方法は?

最も近いのはQuery.suffix_with(*suffixes)ですが、これは接尾辞をテーブルの最後ではなくクエリの最後に置きます。

私のクエリは現在、次のとおりです:

query = session.query(A).options(
    subqueryload(A.rel1), 
    subqueryload(A.rel2) 
).filter(A.id >= min_id, A.id < max_id, [...]) 

と私は効率的のサブセットのみを読み込むことができるようにテーブルA上にTABLESAMPLEをしたいと思い、それが助け場合

が、これは私のユースケースでありますAとそれらの対応関係、いくつかのフィルタ。私はデータベースとしてPostgreSQL 9.5を使用しています。選択可能のため

答えて

4

更新

SQLAlchemy 1.1 and newer support TABLESAMPLEFromClause要素は、例えば、宣言型モデルクラス、メソッドFromClause.tablesample()Table Sを考える)とsqlalchemy.tablesample()機能はすべて選択可能で使用することができます:

from sqlalchemy import tablesample, func 
from sqlalchemy.orm import aliased 

# Create an alias for A that uses SYSTEM sampling method (default) 
a_sampled = aliased(A, tablesample(A, 2.5)) 

# Create an alias for A that uses BERNOULLI sampling method 
a_bernoulli = aliased(A, tablesample(A, func.bernoulli(2.5))) 

Aは宣言クラスであることtablesample(A, ...)のわずかな非対称性は、あります、リターンをa TableSample from-clauseは、モデルとして使用された場合にエイリアスする必要があります。それ以外の場合は、FromClauseのようになります。 Tableはモデルクラスの基礎となります。


これを書いている時点でno discussionTABLESAMPLEについてのサポートがあるようです。 TABLESAMPLEサポートの実装:SQLAlchemyのは非常にextensibleあるので、ここでは(すべてのユースケースのために動作しない場合があります読んで):非常に簡単です

from sqlalchemy.ext.compiler import compiles 
from sqlalchemy.sql import Alias, FromClause 
from sqlalchemy.orm import aliased 


class TableSample(Alias): 

    __visit_name__ = 'tablesample' 

    def __init__(self, selectable, argument=None, method=None, 
       seed=None): 
     super(TableSample, self).__init__(selectable) 
     self.method = method 
     self.argument = argument 
     self.seed = seed 


def tablesample(element, argument=None, method=None, seed=None): 
    if isinstance(element, FromClause): 
     return TableSample(element, argument=argument, method=method, seed=seed) 
    else: 
     return aliased(element, TableSample(element.__table__, 
      argument=argument, method=method, seed=seed)) 


@compiles(TableSample) 
def compile_tablesample(element, compiler, **kwargs): 
    s = "%s TABLESAMPLE %s(%s)" % (
     compiler.visit_alias(element, **kwargs), 
     element.method or 'SYSTEM', 
     element.argument) 

    if element.seed: 
     s += " REPEATABLE (%s)" % compiler.process(element.seed, **kwargs) 

    return s 

argumentが0の間の割合を表すだけでフロート当分の間であるべきで、 PostgreSQLは実数表現を受け入れますが、便宜上、100を使用しています。一方、seedはコンパイルされているので、リテラルなpython値はliteral()などで囲まれていなければなりません。それはaliasedと同様の方法で使用されるべき

a_sampled = tablesample(A, 2.5) 

query = session.query(a_sampled).options(
    subqueryload(a_sampled.rel1), 
    subqueryload(a_sampled.rel2) 
).filter(a_sampled.id >= min_id, a_sampled.id < max_id, [...]) 

+0

はあまりにもサンプルコードを書いていただき、ありがとうございます!私はポインタに満足しています、これはちょうど期待を超えています。 –

関連する問題