Hi all! I’m currently working on a GSoC project to improve the search backend provided in the Wagtail CMS, which is based on Django.
The issue I’ve run into is that I need to create different models for each specific database system that the user may have. That’s because different database systems implement full-text search capabilities in varying approaches.
For example, in PostgreSQL you may want to have a table with the following definition:
CREATE TABLE fts(original_text text, stemmed_text tsvector);
On top of that, you could use a
GIN index on the
stemmed_text column, to improve full-text search performance.
However, this could be implemented in SQLite as:
CREATE VIRTUAL TABLE fts USING FTS5(original_text);
You would not use a
GIN index here. They’re not even supported by SQLite.
As you see, the syntax is fundamentally different. On PostgreSQL, the
stemmed_text column needs to be created, while there’s no need to have additional columns on SQLite. Therefore, it looks like the models themselves are different.
This seems like a reason to use conditional declaration of the models, meaning that only one of the models would get defined, depending on which database system we’re using.
if connection.vendor == 'postgresql': class PostgreSQLModel(models.Model): original_text = TextField() stemmed_text = SearchVectorField() elif connection.vendor == 'sqlite': class SQLiteModel(models.Model): original_text = TextField()
This means that, when the user is using a PostgreSQL database, the
PostgreSQLModel will get picked up by Django, but not the
SQLiteModel; and vice versa.
Is this a reasonable approach? Can you think of a better, more orthodox implementation?