2017-09-08 1 views
1

Ich möchte eine Methode schreiben, die eine update-Anweisung generiert, ohne Spalten und Werte hart zu codieren. Die Anweisung enthält optional where Klausel und wird an executemany übergeben werden, enthält die Klausel nur Spalten und Werte, gibt es keine select drin. Beispiel:Umgang mit null in update where-Klausel ohne hartcodieren einer Anweisung

update TABLE 
set 
    Col1 = 'a', 
    Col2 = 'b', 
    Col3 = 'c' 
where 
    Col4 = 'd' 
     and Col5 = 'e' 
     and Col1 is null; 

Was habe ich bisher:

def update(self, table_name, update_columns, values, where_columns=None, where=True): 
    update_columns_and_values = self.generator.generateColumnsAndPlaceholders(update_columns) 
    if where: 
     where_clause = self.generator.generateWhereClause(where_columns) 
    else: 
     where_clause = '' 
    query = ''' 
      update {t} 
      set 
       {cv} 
      {w} 
     '''.format(t=table_name, cv=update_columns_and_values, w=where_clause) 
    self.cursor.executemany(query, values) 
    self.connection.commit() 

def generateColumnsAndPlaceholders(columns): 
    if type(columns) is str: 
     columns = columns.split(', ') 
    return ', \n'.join([str(c) + ' = ' + "'%s'" for c in columns]) 

Nun, wie soll ich schreiben eine Funktion generateWhereClause, die eine beliebige Anzahl von Spalten nimmt und gibt eine where Klausel mit Platzhalter eingestellt sowohl für einen nicht null Wert (angezeigt mit =) und ein Nullwert (angezeigt mit is null)? Auch denke ich, dass String von generateColumnsAndPlaceholders nicht für null aufgrund von einfachen Anführungszeichen um Platzhalter bereit ist. Wenn ja, wie sollte ich es ändern?

Im Allgemeinen, wie gehe ich mit null in Update-Anweisung ohne hard-coding spezifische Anweisung?

Antwort

1

Die Funktion, die die Abfrage erzeugt - es dauert Tabellenname, Wörterbuch der Werte für Spalten {column: value} und Wörterbuch von Einschränkungen, die keine als Einschränkung respektiert {column: constraint}

def update_query(table_name, values, constraints): 
    v_list = [k + '=' + '"' + v + '"' for k, v in values.iteritems()] 
    v_query = ', '.join(v_list) 
    c_list = [k + (' IS NULL' if c is None else '=' + '"' + c + '"') for k, c in constraints.iteritems()] 
    c_query = ' AND '.join(c_list) 
    return 'UPDATE ' + table_name + ' SET ' + v_query + ' WHERE ' + c_query 

Prüfregeln:

tn = "table" 
vl = {"Col1":"a","Col2":"b","Col3":"c"} 
cn = {"Col4":"d","Col5":"e","Col":None} 

Ergebnis:

UPDATE table SET Col2="b", Col3="c", Col1="a" WHERE Col6 IS NULL AND Col4="d" AND Col5="e" 

I h Die Reihenfolge ist für Sie kein Problem.