Skip to content

Commit c0d34ea

Browse files
authored
Merge pull request piccolo-orm#37 from piccolo-orm/duplicate_index_error
fixing bug with duplicate Table.create(if_not_exists=True) calls and indexes
2 parents b01606c + 5d4505d commit c0d34ea

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

piccolo/query/methods/create.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ def querystrings(self) -> t.Sequence[QueryString]:
4747
if column._meta.index:
4848
create_indexes.extend(
4949
CreateIndex(
50-
table=self.table, columns=[column]
50+
table=self.table,
51+
columns=[column],
52+
if_not_exists=self.if_not_exists,
5153
).querystrings
5254
)
5355

piccolo/query/methods/create_index.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ def __init__(
2323
table: t.Type[Table],
2424
columns: t.List[t.Union[Column, str]],
2525
method: IndexMethod = IndexMethod.btree,
26+
if_not_exists: bool = False,
2627
):
2728
self.columns = columns
2829
self.method = method
30+
self.if_not_exists = if_not_exists
2931
super().__init__(table)
3032

3133
@property
@@ -34,6 +36,13 @@ def column_names(self) -> t.List[str]:
3436
i._meta.name if isinstance(i, Column) else i for i in self.columns
3537
]
3638

39+
@property
40+
def prefix(self) -> str:
41+
prefix = "CREATE INDEX"
42+
if self.if_not_exists:
43+
prefix += " IF NOT EXISTS"
44+
return prefix
45+
3746
@property
3847
def postgres_querystrings(self) -> t.Sequence[QueryString]:
3948
column_names = self.column_names
@@ -43,8 +52,8 @@ def postgres_querystrings(self) -> t.Sequence[QueryString]:
4352
column_names_str = ", ".join(column_names)
4453
return [
4554
QueryString(
46-
f"CREATE INDEX {index_name} ON {tablename} USING {method_name}"
47-
f" ({column_names_str})"
55+
f"{self.prefix} {index_name} ON {tablename} USING "
56+
f"{method_name} ({column_names_str})"
4857
)
4958
]
5059

@@ -61,7 +70,7 @@ def sqlite_querystrings(self) -> t.Sequence[QueryString]:
6170
column_names_str = ", ".join(column_names)
6271
return [
6372
QueryString(
64-
f"CREATE INDEX {index_name} ON {tablename} "
73+
f"{self.prefix} {index_name} ON {tablename} "
6574
f"({column_names_str})"
6675
)
6776
]

tests/table/test_create.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,23 @@ def test_create_table_with_indexes(self):
2929
index_names = BandMember.indexes().run_sync()
3030
index_name = BandMember._get_index_name(["name"])
3131
self.assertTrue(index_name in index_names)
32+
33+
def test_create_if_not_exists_with_indexes(self):
34+
"""
35+
Make sure that if the same table is created again, with the
36+
`if_not_exists` flag, then no errors are raised for duplicate indexes
37+
(i.e. the indexes should also be created with IF NOT EXISTS).
38+
"""
39+
query = BandMember.create_table(if_not_exists=True)
40+
41+
# Shouldn't raise any errors:
42+
query.run_sync()
43+
44+
self.assertTrue(
45+
query.querystrings[0]
46+
.__str__()
47+
.startswith("CREATE TABLE IF NOT EXISTS"),
48+
query.querystrings[1]
49+
.__str__()
50+
.startswith("CREATE INDEX IF NOT EXISTS"),
51+
)

0 commit comments

Comments
 (0)