I believe the basics of how to make it migration friendly would simply be
to make sure it is given in the field's `deconstruct` method. The Index
class may also need to provide a `as_remove_sql(self, qn, connection)`
method which would return the relevant `DROP INDEX` command for the db.

I think it might also be nice to allow the indexes to be overriden at field
create time, so that I can do something like `CharField(max_length=255,
db_indexes=[StandardIndex, BTreeIndex])` so I don't have to create a custom
field subclass in order to add a db-specific index.

M


On 15 October 2013 10:32, Anssi Kääriäinen <[email protected]> wrote:

> On Monday, September 23, 2013 5:36:56 PM UTC+3, Zev Benjamin wrote:
>>
>> Hi,
>>
>> I'd like to be able to specify what kind of index the database should use
>> for a particular field.  I have a proof of concept branch that works with
>> PostgreSQL at 
>> https://github.com/zbenjamin/**django/compare/index-types<https://github.com/zbenjamin/django/compare/index-types>,
>> but I'd like to solicit opinions on whether there's a better way of doing
>> it.  The way it works in my branch is that you specify the index type by
>> making the Field db_index argument a string containing the name of the
>> index type you'd like to use.  Specifying db_index=True uses the default
>> index type.
>>
>> Example usage:
>>
>> class IndexTest(models.Model):
>>     unindexed = models.IntegerField(db_index=**False)
>>     default_indexed = models.IntegerField(db_index=**True)
>>     btree_indexed = models.IntegerField(db_index="**btree")
>>     hash_indexed = models.IntegerField(db_index="**hash")
>>
>
> I have been trying to make contrib.gis to use less private APIs. While
> doing that it became evident that a better way for creating custom indexes
> is needed. Django's contrib.gis needs to override backend's private methods
> so that indexes can be created. This approach doesn't work if you need
> multiple different custom index types (and overriding private methods
> itself is a bad habit). For example, a 3rd party PostgreSQL field (say
> trigram field) would need custom indexes to work efficiently, but there is
> no easy way to do that currently (unless migrations have added something to
> allow this?).
>
> I don't want to add a couple more index types to core and leave it to
> that. The solution must allow for 3rd party apps to create any index they
> need.
>
> One possible solution idea is to add a get_index_definitions(self,
> connection) method to Field. By default the Field's
> get_index_definitions(self, connection) method will return
> [StandardIndex(self)] if any index is needed by the field, else []. For
> contrib.gis it would be something like super(GeometryField,
> self).get_index_definitions(connection).append(GeometryIndex(self)) (Of
> course, only if self.spatial_index == True).
>
> Index class instances have an as_sql(self, qn, connection) method. A core
> index definition's as_sql() would need to call back to connection (so that
> 3rd party backends are supported). For example, StandardIndex.as_sql()
> would be this:
>     return connection.creation.standard_index_sql(self)
>
> A 3rd party trigram field's index could use something like this:
>    if connection.vendor == 'postgresql':
>         return 'CREATE INDEX trgm_idx ON %s USING gist (%s gist_trgm_ops)'
> % (qn(self.field.model._meta.db_table), qn(self.field.column))
>    elif hasattr(connection.creation, 'create_trgm_index'):
>         return connection.creation.create_trgm_index(self)  # any custom
> backend could implement trigram index.
>    raise NotSupportedException(("The connection %s doesn't support trgm
> indexes")
>
> With virtual fields you could have fields that do not do anything else
> than create an index. So:
>
> class MyModel(models.Model):
>     a = models.IntegerField()
>     b = models.IntegerField()
>     my_composite_hash_index = HashIndex(a, b) # HashIndex is a virtual
> field that implements get_index_definitions() method, but doesn't do
> anything else for the model.
>
> This same concept might be extended to other custom SQL (comments, check
> constraints, storage parameters, ...).
>
> I don't know how this idea combines with migrations framework. Anybody
> have any idea of how to make this idea migrations friendly?
>
>  - Anssi
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/e82f538b-6a8b-4691-ad8f-3912d87599ed%40googlegroups.com
> .
>
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAMwjO1FJZeJJGCFOyN-5_Z2q5wppF_5QYWvvNy%3DCGNT5DrvgSA%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to