Skip to content

Commit 76f6d4b

Browse files
authored
Merge pull request piccolo-orm#72 from piccolo-orm/expose_index_options
Expose index options
2 parents 6bcfa66 + f255f33 commit 76f6d4b

File tree

8 files changed

+63
-20
lines changed

8 files changed

+63
-20
lines changed

piccolo/apps/migrations/auto/migration_manager.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,12 +404,32 @@ async def _run_alter_columns(self, backwards=False):
404404
).run()
405405

406406
index = params.get("index")
407-
if index is not None:
407+
index_method = params.get("index_method")
408+
if index is None:
409+
if index_method is not None:
410+
# If the index value hasn't changed, but the
411+
# index_method value has, this indicates we need
412+
# to change the index type.
413+
column = Column()
414+
column._meta._table = _Table
415+
column._meta._name = column_name
416+
await _Table.drop_index([column]).run()
417+
await _Table.create_index(
418+
[column], method=index_method, if_not_exists=True
419+
).run()
420+
else:
421+
# If the index value has changed, then we are either
422+
# dropping, or creating an index.
408423
column = Column()
409424
column._meta._table = _Table
410425
column._meta._name = column_name
411-
if index:
412-
await _Table.create_index([column]).run()
426+
if index is True:
427+
kwargs = (
428+
{"method": index_method} if index_method else {}
429+
)
430+
await _Table.create_index(
431+
[column], if_not_exists=True, **kwargs
432+
).run()
413433
else:
414434
await _Table.drop_index([column]).run()
415435

piccolo/columns/base.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@
2727
from piccolo.columns.combination import Where
2828
from piccolo.columns.defaults.base import Default
2929
from piccolo.columns.reference import LazyTableReference
30+
from piccolo.columns.indexes import IndexMethod
3031
from piccolo.querystring import QueryString
3132
from piccolo.utils.warnings import colored_warning
3233

3334
if t.TYPE_CHECKING: # pragma: no cover
34-
from piccolo.table import Table
3535
from piccolo.columns.column_types import ForeignKey
36+
from piccolo.table import Table
3637

3738

3839
class OnDelete(str, Enum):
@@ -120,6 +121,7 @@ class ColumnMeta:
120121
key: bool = False
121122
unique: bool = False
122123
index: bool = False
124+
index_method: IndexMethod = IndexMethod.btree
123125
required: bool = False
124126

125127
# Used for representing the table in migrations and the playground.
@@ -231,9 +233,12 @@ class Column(Selectable):
231233
If set, a unique contraint will be added to the column.
232234
233235
:param index:
234-
If set, the an index is created for the column, which can improve
236+
Whether an index is created for the column, which can improve
235237
the speed of selects, but can slow down inserts.
236238
239+
:param index_method:
240+
If index is set to True, this specifies what type of index is created.
241+
237242
:param required:
238243
This isn't used by the database - it's to indicate to other tools that
239244
the user must provide this value. Example uses are in serialisers for
@@ -250,6 +255,7 @@ def __init__(
250255
key: bool = False,
251256
unique: bool = False,
252257
index: bool = False,
258+
index_method: IndexMethod = IndexMethod.btree,
253259
required: bool = False,
254260
**kwargs,
255261
) -> None:
@@ -263,6 +269,7 @@ def __init__(
263269
"key": key,
264270
"unique": unique,
265271
"index": index,
272+
"index_method": index_method,
266273
}
267274
)
268275

@@ -278,6 +285,7 @@ def __init__(
278285
key=key,
279286
unique=unique,
280287
index=index,
288+
index_method=index_method,
281289
params=kwargs,
282290
required=required,
283291
)

piccolo/columns/indexes.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from enum import Enum
2+
3+
4+
class IndexMethod(str, Enum):
5+
btree = "btree"
6+
hash = "hash"
7+
gist = "gist"
8+
gin = "gin"
9+
10+
def __str__(self):
11+
return f"{self.__class__.__name__}.{self.name}"
12+
13+
def __repr__(self):
14+
return self.__str__()

piccolo/query/methods/create.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ def querystrings(self) -> t.Sequence[QueryString]:
4444

4545
create_indexes: t.List[QueryString] = []
4646
for column in columns:
47-
if column._meta.index:
47+
if column._meta.index is True:
4848
create_indexes.extend(
4949
CreateIndex(
5050
table=self.table,
5151
columns=[column],
52+
method=column._meta.index_method,
5253
if_not_exists=self.if_not_exists,
5354
).querystrings
5455
)

piccolo/query/methods/create_index.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,15 @@
11
from __future__ import annotations
2-
from enum import Enum
32
import typing as t
43

54
from piccolo.columns import Column
5+
from piccolo.columns.indexes import IndexMethod
66
from piccolo.query.base import Query
77
from piccolo.querystring import QueryString
88

99
if t.TYPE_CHECKING: # pragma: no cover
1010
from piccolo.table import Table
1111

1212

13-
class IndexMethod(str, Enum):
14-
btree = "btree"
15-
hash = "hash"
16-
gist = "gist"
17-
gin = "gin"
18-
19-
2013
class CreateIndex(Query):
2114
def __init__(
2215
self,

piccolo/table.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
LAZY_COLUMN_REFERENCES,
1717
)
1818
from piccolo.columns.defaults.base import Default
19+
from piccolo.columns.indexes import IndexMethod
1920
from piccolo.query import (
2021
Alter,
2122
Count,
@@ -31,7 +32,7 @@
3132
Update,
3233
)
3334
from piccolo.query.methods.indexes import Indexes
34-
from piccolo.query.methods.create_index import CreateIndex, IndexMethod
35+
from piccolo.query.methods.create_index import CreateIndex
3536
from piccolo.querystring import QueryString, Unquoted
3637
from piccolo.utils import _camel_to_snake
3738

@@ -622,14 +623,20 @@ def create_index(
622623
cls,
623624
columns: t.List[t.Union[Column, str]],
624625
method: IndexMethod = IndexMethod.btree,
626+
if_not_exists: bool = False,
625627
) -> CreateIndex:
626628
"""
627629
Create a table index. If multiple columns are specified, this refers
628630
to a multicolumn index, rather than multiple single column indexes.
629631
630632
await Band.create_index([Band.name]).run()
631633
"""
632-
return CreateIndex(table=cls, columns=columns, method=method)
634+
return CreateIndex(
635+
table=cls,
636+
columns=columns,
637+
method=method,
638+
if_not_exists=if_not_exists,
639+
)
633640

634641
@classmethod
635642
def drop_index(

tests/apps/migrations/auto/test_schema_differ.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def test_add_table(self):
3737
self.assertTrue(len(new_table_columns.statements) == 1)
3838
self.assertEqual(
3939
new_table_columns.statements[0],
40-
"manager.add_column(table_class_name='Band', tablename='band', column_name='name', column_class_name='Varchar', column_class=Varchar, params={'length': 255, 'default': '', 'null': False, 'primary': False, 'key': False, 'unique': False, 'index': False})", # noqa
40+
"manager.add_column(table_class_name='Band', tablename='band', column_name='name', column_class_name='Varchar', column_class=Varchar, params={'length': 255, 'default': '', 'null': False, 'primary': False, 'key': False, 'unique': False, 'index': False, 'index_method': IndexMethod.btree})", # noqa
4141
)
4242

4343
def test_drop_table(self):
@@ -119,7 +119,7 @@ def test_add_column(self):
119119
self.assertTrue(len(schema_differ.add_columns.statements) == 1)
120120
self.assertEqual(
121121
schema_differ.add_columns.statements[0],
122-
"manager.add_column(table_class_name='Band', tablename='band', column_name='genre', column_class_name='Varchar', column_class=Varchar, params={'length': 255, 'default': '', 'null': False, 'primary': False, 'key': False, 'unique': False, 'index': False})", # noqa
122+
"manager.add_column(table_class_name='Band', tablename='band', column_name='genre', column_class_name='Varchar', column_class=Varchar, params={'length': 255, 'default': '', 'null': False, 'primary': False, 'key': False, 'unique': False, 'index': False, 'index_method': IndexMethod.btree})", # noqa
123123
)
124124

125125
def test_drop_column(self):

tests/table/test_str.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ def test_str(self):
99
Manager._table_str(),
1010
(
1111
"class Manager(Table, tablename='manager'):\n"
12-
" id = PrimaryKey(null=False, primary=True, key=True, unique=False, index=False)\n" # noqa
13-
" name = Varchar(length=50, default='', null=False, primary=False, key=False, unique=False, index=False)\n" # noqa
12+
" id = PrimaryKey(null=False, primary=True, key=True, unique=False, index=False, index_method=IndexMethod.btree)\n" # noqa
13+
" name = Varchar(length=50, default='', null=False, primary=False, key=False, unique=False, index=False, index_method=IndexMethod.btree)\n" # noqa
1414
),
1515
)
1616

0 commit comments

Comments
 (0)