2015-03-22 18 views
9

Prima volta sul sito, quindi ciao a tutti e grazie in anticipo. Lurker e newb di lunga data.Flask-Sqlalchemy + Sqlalchemy: elenco vuoto restituibile ricercabile

Sto lavorando a un'app Web in una fiaschetta, utilizzando Flask-SqlAlchemy e SqlAlchemy-Ricercabile (documenti->https://sqlalchemy-searchable.readthedocs.org/en/latest/index.html). Per una ragione che non riesco a capire, quando provo un esempio simile al codice mostrato sulla pagina docs:

from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy, BaseQuery 
from sqlalchemy_searchable import SearchQueryMixin 
from sqlalchemy_utils.types import TSVectorType 
from sqlalchemy_searchable import make_searchable 

app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://usr:[email protected]/dev' 
app.config['SECRET_KEY'] = 'notreallyasecret' 
db = SQLAlchemy(app) 
make_searchable() 


class ArticleQuery(BaseQuery, SearchQueryMixin): 
    pass 


class Article(db.Model): 
    query_class = ArticleQuery 
    __tablename__ = 'article' 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.Unicode(255)) 
    content = db.Column(db.UnicodeText) 
    search_vector = db.Column(TSVectorType('name', 'content')) 

mie query di ricerca non funzionano correttamente. Aprii un guscio pitone e creato il db, e inserito cinque articoli identici

a= Article(name='finland',content='finland') 
db.session.add(a) 
db.session.commit() #a-e 

con 'Finlandia' sia come nome e il contenuto. Secondo l'esempio:

Article.query.search(u'finland').limit(5).all() 

Ci devono essere articoli restituiti che hanno finlandia da qualche parte in loro. Nel mio caso, ottengo una lista vuota. Ottengo un oggetto indietro se modifico la query di esempio per:

Article.query.search(' ').first() 

Ma è piuttosto la ricerca inutile per gli spazi vuoti. Qualche idea?

Aggiungendo un po 'di più: ho notato nella tabella degli articoli, la colonna' search_vector tsvector 'è completamente vuota nonostante i dati siano presenti nel contenuto e nelle colonne del nome; Non sono sicuro che ciò abbia a che fare con questo.

+0

Odio chiedere una domanda ovvia ... ma sei sicuro che c'è una "Finlandia" nei dati? Credo che la ricerca di sqlalchemy sia sensibile al maiuscolo/minuscolo ... forse i tuoi dati hanno una "Finlandia" ma non "finlandia"? – dylrei

+0

Domanda totalmente valida. Sì, sono certo che sono uguali. In realtà avevo fatto un mucchio di altri dischi, con il nome e il contenuto che erano entrambi "pie". Ho modificato l'originale per rendere la finlandia in tutte le lettere minuscole. – Vyndion

+0

Sembra che non si debba tornare indietro alla ricerca di spazi. Ritirate i 5 "finlandesi" che avete inserito se fate 'Article.query.search ('') .all()'? – dylrei

risposta

8

Mi sono imbattuto in questo problema anche una volta, quando si utilizza Flask-Script per aggiungere uno strumento di gestione manage.py alla mia applicazione.

Il fatto che la colonna search_vector sia vuota nonostante siano stati aggiunti i parametri appropriati TSVectorType significa che l'attivatore ricercabile SQLAlchemy non è presente nel DB postgres. È possibile verificare la sua assenza facendo uno \df+ nello strumento da riga di comando psql - non vedrete un trigger denominato article_search_vector_update. SQLAlchemy-Ricercabile imposta questo trigger per aggiornare il contenuto della colonna search_vector quando le colonne denominate in TSVectorType(...) cambiano.

Nel caso di manage.py, ho dovuto prima chiamata:

db.configure_mappers() 

In sostanza, è necessario configurare mapper di SQLAlchemy prima chiamata create_all(). Senza fare ciò, SQLAlchemy-Searchable non avrà la possibilità di aggiungere il suo trigger search_vector per popolare la colonna TSVectorType nel modello. Il SQLAlchemy-Searchable docs ha più su questo.

In totale, un minimo manage.py che configura correttamente SQLAlchemy ricercabile come richiedete potrebbe essere simile:

#!/usr/bin/env python 

from flask.ext.script import Manager 
from app import app, db 

manager = Manager(app) 

@manager.command 
def init_db(): 
    """ 
    Drops and re-creates the SQL schema 
    """ 
    db.drop_all() 
    db.configure_mappers() 
    db.create_all() 
    db.session.commit() 
6

Sulla risposta di Collin Allen: in realtà, il pallone-sqlalchemy '' db '' espone la funzione configure_mappers .

Sostituire:

from sqlalchemy.orm.mapper import configure_mappers 
... 
configure_mappers() 

con:

... 
db.configure_mappers() 
+0

In effetti, questo funziona benissimo! Ho modificato la mia risposta per riflettere la tua nota. Grazie! –

Problemi correlati