2010-09-13 8 views
0

J'ai une chaîne SQL, par exempleRemplacement une partie de chaîne avec Python

SELECT * FROM benchmark WHERE xversion = 1.0 

Et en fait, xversion est variable aliasées et self.alias a toutes les informations d'alias quelque chose comme

 
{'CompilationParameters_Family': 'chip_name', 
'xversion': 'CompilationParameters_XilinxVersion', 'opt_param': 
    .... 
'chip_name': 'CompilationParameters_Family', 
'CompilationParameters_Device': 'device'} 

En utilisant cet alias, je devrais changer la chaîne comme suit.

SELECT * FROM benchmark WHERE CompilationParameters_XilinxVersion = 1.0 

Pour cette modification, j'ai trouvé ce qui suit.

def processAliasString(self, sqlString): 
    components = sqlString.split(' ') 
    resList = [] 
    for comp in components: 
     if comp in self.alias: 
      resList.append(self.alias[comp]) 
     else: 
      resList.append(comp) 
    resString = " ".join(resList) 
    return resString 

Mais, je m'attends à un meilleur code ne pas utiliser pour la boucle. Qu'est-ce que tu penses?

+0

Je peux voir une faiblesse potentielle dans votre code. Pensez à ce qui se passe si 'self.alias' est dit, comme ceci:' {'SELECT': 'DROP', '*': 'TABLE', 'FROM': '', 'WHERE': '; } '. –

Répondre

1

Si vous pouviez changer le format de votre chaîne d'entrée pour rendre les remplacements plus clairement visibles, par exemple

s = 'SELECT * FROM benchmark WHERE %(xversion)s = 1.0' 

alors s % self.alias suffirait (il existe d'autres alternatives disponibles en fonction de votre syntaxe de formatage préféré et niveau Python). Si le format de chaîne d'entrée est "cloué", re peut aider en raison de la facilité qu'il offre pour identifier les limites de mots (ainsi vous ne manquerez pas par inadvertance un remplacement si un espace autrement insignifiant est manquant, par exemple après xversion). Tenez compte (avec s ayant sa forme originale, avec substitutables mélangés au petit bonheur avec les non-substitutables):

import re 
sre = re.compile('|'.join(r'\b%s\b' % re.escape(s) for s in self.alias)) 
def repl(mo): 
    return self.alias[mo.group()] 
news = sre.sub(repl, s) 

Ces approches sont rapides, puisque % -Format et re s'sub sont très bien optimisé pour ces tâches.

+0

Merci pour la merveilleuse astuce. Malheureusement, l'utilisateur me donne une commande SQL, donc pour utiliser votre code, je devrais analyser pour savoir exactement quelle partie de la chaîne devrait être modifiée, ce qui est pratiquement impossible maintenant. – prosseek

+0

@prosseek, vous pouvez, cependant, utiliser le code 're' dans la deuxième partie de ma réponse (sans risques d'espaces insignifiants manquants, comme ce serait le cas avec une approche' .split() '). –

+0

Je vois, merci pour l'aide à nouveau. – prosseek

1

Cela devrait le faire:

def processAliasString(self, sqlString): 
    return ' '.join(self.alias.get(comp, comp) for comp in sqlString.split(' ')) 
Questions connexes