2012-11-13 16 views
9

मैं फ्लास्क, स्क्लेल्चेमी और फ्लास्क-स्क्लेल्चेमी का उपयोग कर रहा हूं। मैं gin और to_tsvector के साथ पोस्टग्रेस में एक पूर्ण परीक्षण खोज अनुक्रमणिका बनाना चाहता हूं। फिलहाल, मैं निम्नलिखित कोशिश कर रहा हूं। मुझे लगता है कि यह सबसे नज़दीकी है जो मुझे व्यक्त करने की कोशिश कर रहा है, लेकिन काम नहीं करता है।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 को कॉल करने की अपेक्षा करता है। यह लाइन एसक्यूएल बनाता है;

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

'column.key' बनाम' column.name' उपयोग से संबंधित एक फिक्स था जिसे पोस्ट-0.8.0 बीटा – 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')) 

एसक्यूएलकेमी बग ट्रैकर पर कुछ रोचक चर्चा हुई। ऐसा लगता है कि यह वर्तमान अनुक्रमण परिभाषा की एक सीमा है। असल में, मेरी आवश्यकता है कि इंडेक्स को केवल कॉलम नामों के बजाय अभिव्यक्तियों की अनुमति दें, लेकिन वर्तमान में यह समर्थित नहीं है। यह टिकट इस सुविधा अनुरोध को ट्रैक कर रहा है: http://www.sqlalchemy.org/trac/ticket/695। हालांकि, यह एक डेवलपर को आगे बढ़ने और काम करने की प्रतीक्षा कर रहा है (और थोड़ी देर के लिए रहा है)।

1

तो SQLAlchemy 0.9 में और इस काम करता है:

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: कॉलम संग्रह में अनामित कॉलम नहीं जोड़ सकता –