2012-11-13 48 views
9

Tôi đang sử dụng bình, sqlalchemy và bình phương sqlalchemy. Tôi muốn tạo chỉ mục tìm kiếm thử nghiệm đầy đủ trong postgres với gin và to_tsvector. Tại thời điểm này, tôi đang cố gắng sau đây. Tôi nghĩ rằng nó gần nhất tôi đã có những gì tôi đang cố gắng để thể hiện, nhưng không hoạt động.SQLAlchemy với PostgresSQL và Tìm kiếm Toàn văn Tìm kiếm

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"),) 

này ném các lỗi sau ...

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' 

Tôi cũng đã thử

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

Tuy nhiên, nó không hoạt động như postgres (9.1 ít nhất, vì đó là những gì tôi chạy) hy vọng to_tsvector được gọi. Dòng này tạo ra SQL;

CREATE INDEX content_index ON post USING gin (content) 

thay vì những gì tôi muốn;

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

Tôi đã mở một vé vì tôi cho rằng đây có thể là lỗi/giới hạn. http://www.sqlalchemy.org/trac/ticket/2605

+1

Phiên bản SQLAlchemy là gì? – plaes

+0

0.8.0 beta. Tuy nhiên, tôi cũng đã thử 0.7.2 (tôi nghĩ - bản ổn định mới nhất). – d0ugal

+1

Có một sửa chữa liên quan đến 'column.key' so với' column.name' sử dụng được áp dụng sau 0.8.0beta – plaes

Trả lời

4

Hiện tại tôi đã thêm các dòng sau để thực hiện thủ công, nhưng tôi muốn sử dụng phương pháp SQLAlchemy 'đúng' nếu có.

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')) 

Có một số cuộc thảo luận thú vị về trình theo dõi lỗi SQLAlchemy. Có vẻ như đây là giới hạn của định nghĩa lập chỉ mục hiện tại. Về cơ bản, yêu cầu của tôi là cho phép các chỉ mục trở thành các biểu thức chứ không chỉ là các tên cột nhưng hiện không được hỗ trợ. Vé này đang theo dõi yêu cầu tính năng này: http://www.sqlalchemy.org/trac/ticket/695. Tuy nhiên, điều này là chờ đợi cho một nhà phát triển để đi về phía trước và làm công việc (và đã được một thời gian).

1

Vì vậy, trong SQLAlchemy 0.9 và lên này hoạt động:

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"),) 

Đáng chú ý, sự khác biệt từ ví dụ đầu tiên là một tham chiếu trực tiếp đến tên cột, như trái ngược với tên cột được cung cấp trong dấu ngoặc kép, vì điều đó đã không làm việc.

+0

Tôi đang thử điều này trên 0.9.8 và nó không. Dấu ngắt với: 'sqlalchemy.exc.ArgumentError: Không thể thêm cột chưa được đặt tên vào tập hợp cột' –

Các vấn đề liên quan