[FIXED] SQLAlchemy mit PostgreSQL und Volltextsuche

Ausgabe

Ich verwende Flask, Sqlalchemy und Flask-Sqlalchemy. Ich möchte einen vollständigen Testsuchindex in Postgres mit Gin und to_tsvector erstellen. Im Moment versuche ich folgendes. Ich denke, es kommt dem, was ich auszudrücken versuche, am nächsten, aber es funktioniert nicht.

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

Dies wirft den folgenden Fehler …

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'

Ich habe es auch versucht

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

Es funktioniert jedoch nicht, da Postgres (mindestens 9.1, da ich das ausführe) erwartet, dass to_tsvector aufgerufen wird. Diese Zeile erstellt das SQL;

CREATE INDEX content_index ON post USING gin (content)

eher als das, was ich will;

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

Ich habe ein Ticket eröffnet, da ich denke, dass dies ein Fehler/eine Einschränkung sein könnte. http://www.sqlalchemy.org/trac/ticket/2605

Lösung

Im Moment habe ich die folgenden Zeilen hinzugefügt, um dies manuell zu tun, aber ich würde viel lieber den “richtigen” SQLAlchemy-Ansatz verwenden, falls es einen gibt.

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

Es gab einige interessante Diskussionen zum Bugtracker von SQLAlchemy. Es sieht so aus, als ob dies eine Einschränkung der aktuellen Indizierungsdefinition ist. Grundsätzlich ist meine Anforderung, dass Indizes Ausdrücke und nicht nur Spaltennamen sein dürfen, aber das wird derzeit nicht unterstützt. Dieses Ticket verfolgt diese Funktionsanfrage: http://www.sqlalchemy.org/trac/ticket/695 . Dies wartet jedoch darauf, dass ein Entwickler voranschreitet und die Arbeit erledigt (und das schon seit einer Weile).


Beantwortet von –
d0ugal


Antwort geprüft von –
David Goodson (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like