1

django 拡張機能 djorm-ext-pgfulltext を使用しているときに SQL サブクエリを実行すると生成されるエラーを解決しようとしています。

発生するエラーは

テーブル "bookmarks_bookmark" の FROM 句エントリへの無効な参照 LINE 1: ...ECT U0."id" FROM "bookmarks_bookmark" U0 WHERE ( ("bookmarks... ^ ヒント: おそらく、テーブル エイリアス "u0" を参照するつもりだった可能性があります"。

エラーを生成するdjangoクエリセットフィルターは

shared_bookmarks = SharedBookmark.objects.filter(bookmark__in=Bookmark.objects.search(query))

query='html' の場合に生成される sql は次のとおりです。

SELECT "bookmarks_sharedbookmark"."id", "bookmarks_sharedbookmark"."created", "bookmarks_sharedbookmark"."modified", "bookmarks_sharedbookmark"."bookmark_id", "bookmarks_sharedbookmark"."hot_score" FROM "bookmarks_sharedbookmark" WHERE "bookmarks_sharedbookmark"."ブックマーク ID" IN (SELECT U0."id" FROM U0 WHERE ( (U0."検索インデックス") @@ (plainto_tsquery('pg_catalog.english', 'html'))))

私が調査できたことから、問題は djorm-ext-pgfulltext の extra() 関数、具体的には次の行の使用に起因している可能性があります。

qs = qs.extra(select=select_dict, where=[where], order_by=order)

リストを使用してサブクエリを強制的に評価することで、問題を解決できました。

SharedBookmark.objects.filter(bookmark__in=list(Bookmark.objects.search(query))) 

ただし、各要素のロードに関連するメモリのオーバーヘッドは、ある時点で法外なものになります。

メモリのオーバーヘッドをそれほど必要としないエラーを解決したいと思います。extra() の使用に関する問題に関連する django のドキュメントを読み、「生成されたクエリを見て、余分なテーブルに指定されたエイリアスを使用するように where 追加を書き直す」という推奨事項を読みましたが、正しいエイリアスがどこにあるかわかりませんそして、一般的に(検索された用語に対して)問題を処理する適切なSQLを作成する方法。

4

1 に答える 1

1

あなたのエラーについて

SELECT U0."id" FROM "bookmarks_bookmark"クエリにはありません。なんらかの誤解があるはずです。

提示されたクエリについて

EXISTS準結合の別のケース。

SELECT b.id, b.created, b.modified, b.bookmark_id, b.hot_score
FROM   bookmarks_sharedbookmark b
WHERE  EXISTS (
    SELECT 1
    FROM   u0
    WHERE  u0.id = b.bookmark_id
    AND    u0.search_index @@ plainto_tsquery('pg_catalog.english', 'html')
   )

u0の 1 つの行に対して複数の一致がある場合bookmarks_sharedbookmarkEXISTSサブクエリは最初の一致が見つかるとすぐにスキャンを終了できるため、パフォーマンスが大幅に向上します。

于 2013-08-01T17:51:26.573 に答える