diff --git a/docs/python-api.rst b/docs/python-api.rst index 26e9a8d..68ef7e2 100644 --- a/docs/python-api.rst +++ b/docs/python-api.rst @@ -394,6 +394,8 @@ You can create a unique index by passing ``unique=True``:: dogs.create_index(["name"], unique=True) +Use ``if_not_exists=True`` to do nothing if an index with that name already exists. + Vacuum ====== diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index adcd934..996a501 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -236,19 +236,20 @@ class Table: self.exists = True return self - def create_index(self, columns, index_name=None, unique=False): + def create_index(self, columns, index_name=None, unique=False, if_not_exists=False): if index_name is None: index_name = "idx_{}_{}".format( self.name.replace(" ", "_"), "_".join(columns) ) sql = """ - CREATE {unique}INDEX {index_name} + CREATE {unique}INDEX {if_not_exists}{index_name} ON {table_name} ({columns}); """.format( index_name=index_name, table_name=self.name, columns=", ".join(columns), unique="UNIQUE " if unique else "", + if_not_exists="IF NOT EXISTS " if if_not_exists else "", ) self.db.conn.execute(sql) return self diff --git a/tests/test_create.py b/tests/test_create.py index 16b52e2..4c7b550 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -1,9 +1,10 @@ from sqlite_utils.db import Index, Database import collections import datetime +import json import pathlib import pytest -import json +import sqlite3 try: import pandas as pd @@ -188,6 +189,17 @@ def test_create_index_unique(fresh_db): ) +def test_create_index_if_not_exists(fresh_db): + dogs = fresh_db["dogs"] + dogs.insert({"name": "Cleo", "twitter": "cleopaws", "age": 3, "is_good_dog": True}) + assert [] == dogs.indexes + dogs.create_index(["name"]) + assert 1 == len(dogs.indexes) + with pytest.raises(sqlite3.OperationalError): + dogs.create_index(["name"]) + dogs.create_index(["name"], if_not_exists=True) + + @pytest.mark.parametrize( "data_structure", (