2017-05-16 10 views
2

Ich habe eine Alembic-Migration, die ein paar DB-Indizes erstellt, die in einer Datenbank fehlten. Beispiel:Erstellen Sie einen DB-Index, wenn es nicht existiert

op.create_index(op.f('ix_some_index'), 'table_1', ['column_1'], unique=False) 

schlägt jedoch fehl, die Migration in anderen Umgebungen, die bereits den Index:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) relation "ix_some_index" already exists 

PostgreSQL unterstützt eine IF NOT EXISTS Option für Fälle wie diese, aber ich sehe keine Möglichkeit des Aufrufens Es verwendet entweder Alembic oder SQLAlchemy Optionen. Gibt es eine kanonische Möglichkeit, nach einem vorhandenen Index zu suchen?

Antwort

0

Hier ist eine etwas stumpfe Lösung, die für PostgreSQL funktioniert. Es prüft einfach, ob es einen Index mit dem gleichen Namen gibt, bevor der neue Index erstellt wird.

Beachten Sie, dass nicht überprüft wird, ob sich der Index im richtigen Postgres-Namespace oder anderen relevanten Informationen befindet. Es funktioniert in meinem Fall, weil ich weiß, dass es keine andere Möglichkeit, Namenskollision:

def index_exists(name): 
    connection = op.get_bind() 
    result = connection.execute(
     "SELECT exists(SELECT 1 from pg_indexes where indexname = '{}') as ix_exists;" 
      .format(name) 
    ).first() 
    return result.ix_exists 

def upgrade(): 
    if not index_exists('ix_some_index'): 
     op.create_index(op.f('ix_some_index'), 'table_1', ['column_1'], unique=False) 
+0

Es wäre zu verwenden entweder besser 'pg_indexes' statt' pg_class' (das auch Überprüfung des korrekten Schemas machen würde und Tabelle leichter). Wenn Sie pg_class verwenden, wäre es besser, 'relkind = 'i'' anstatt' reltype = 0' zu verwenden. –

+0

@a_horse_with_no_name Danke, ich habe den Code aktualisiert, um 'pg_indexes' zu verwenden. –

Verwandte Themen