2012-11-13 6 views
9

私はフラスコ、sqlalchemy、flask-sqlalchemyを使用しています。私はginとto_tsvectorを使ってpostgresで完全なテスト検索インデックスを作成したいと思っています。現時点では、私は次のことを試しています。私はそれが私が表現しようとしているものに最も近いと思うが、うまくいかない。PostgresSQLとフルテキスト検索を使用したSQLAlchemy

from sqlalchemy.ext.declarative import declared_attr 
from sqlalchemy.schema import Index 
from sqlalchemy.sql.expression import func 

from app import db 


class Post(db.Model): 

    id = db.Column(db.Integer, primary_key=True) 
    added = db.Column(db.DateTime, nullable=False) 
    pub_date = db.Column(db.DateTime, nullable=True) 
    content = db.Column(db.Text) 

    @declared_attr 
    def __table_args__(cls): 
     return (Index('idx_content', func.to_tsvector("english", "content"), postgresql_using="gin"),) 

これは、次のエラーがスローされます...

Traceback (most recent call last): 
    File "./manage.py", line 5, in <module> 
    from app import app, db 
    File "/vagrant/app/__init__.py", line 36, in <module> 
    from pep.models import * 
    File "/vagrant/pep/models.py", line 8, in <module> 
    class Post(db.Model): 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/flask_sqlalchemy.py", line 477, in __init__ 
    DeclarativeMeta.__init__(self, name, bases, d) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/api.py", line 48, in __init__ 
    _as_declarative(cls, classname, cls.__dict__) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 222, in _as_declarative 
    **table_kw) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/schema.py", line 326, in __new__ 
    table._init(name, metadata, *args, **kw) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/schema.py", line 393, in _init 
    self._init_items(*args) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/schema.py", line 63, in _init_items 
    item._set_parent_with_dispatch(self) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/events.py", line 235, in _set_parent_with_dispatch 
    self._set_parent(parent) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/schema.py", line 2321, in _set_parent 
    ColumnCollectionMixin._set_parent(self, table) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/schema.py", line 1978, in _set_parent 
    self.columns.add(col) 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 2391, in add 
    self[column.key] = column 
    File "/home/vagrant/.virtualenvs/pep/local/lib/python2.7/site-packages/sqlalchemy/sql/expression.py", line 2211, in __getattr__ 
    key) 
AttributeError: Neither 'Function' object nor 'Comparator' object has an attribute 'key' 

私も

return (Index('idx_content', "content", postgresql_using="gin"),) 

ことだしかし、それは、少なくともpostgresの(9.1として動作しないを試してみました私が走るもの)はto_tsvectorが呼び出されることを期待しています。この行はSQLを作成します。

CREATE INDEX content_index ON post USING gin (content) 

私が望むものではなく、

CREATE INDEX content_index ON post USING gin(to_tsvector('english', content)) 

これはバグ/制限の可能性があると私は考えてチケットを開いた。 http://www.sqlalchemy.org/trac/ticket/2605

+1

SQLAlchemyのバージョンは何ですか? – plaes

+0

0.8.0ベータ。しかし、私も0.7.2を試しました(私は - 最新の安定したものと思います)。 – d0ugal

+1

post-0.8.0beta – plaes

答えて

4

私はこれを手動で行うために以下の行を追加しましたが、SQLAlchemyの「正しい」アプローチがあれば、むしろその方が正しいでしょう。

create_index = DDL("CREATE INDEX idx_content ON pep USING gin(to_tsvector('english', content));") 
event.listen(Pep.__table__, 'after_create', create_index.execute_if(dialect='postgresql')) 

SQLAlchemyバグトラッカーに関するいくつかの興味深い議論がありました。これは、現在のインデックス定義の制限だと思われます。基本的には、私の要件は、インデックスを単に列名ではなく式にすることですが、現在サポートされていません。このチケットはこの機能要求をトラッキングしています:http://www.sqlalchemy.org/trac/ticket/695。しかし、これは開発者が前進して作業を行うのを待っている(しばらく行っている)。 SQLAlchemyの0.9で、これまでそう

1

動作:

class Content(Base,): 
    __tablename__ = 'content' 

    id = sa.Column(sa.Integer, primary_key=True) 

    description = sa.Column(sa.UnicodeText, nullable=False, server_default='') 
    @declared_attr 
    def __table_args__(cls): 
     return (sa.Index('idx_content', 
        sa.sql.func.to_tsvector("english", cls.description), 
        postgresql_using="gin"),) 

ような、引用符内に設けられている列名を対照として注目すべきは、第一実施例との違いは、列名を直接参照しています動作しませんでした。

+0

私は0.9.8でこれを試していますが、そうではありません。 'sqlalchemy.exc.ArgumentError:列コレクションに名前のない列を追加できません。' –

関連する問題