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?