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)