2008-11-24 9 views
6

Czy ktoś wie, czy istnieje sposób automatycznego rozwinięcia listy w Pythonie, oddzielonej przecinkami? Piszę kod Pythona, który używa biblioteki MySQLdb i próbuję dynamicznie aktualizować listę wierszy w bazie danych MySQL z pewnymi kluczowymi wartościami.Automatyczne rozszerzanie listy w języku Python o sformatowane wyjście

Na przykład w poniższym kodzie chciałbym, aby wartości numeryczne na liście record_ids rozszerzyły się do klauzuli SQL "IN".

import MySQLdb 
record_ids = [ 23, 43, 71, 102, 121, 241 ] 

mysql = MySQLdb.connect(user="username", passwd="secret", db="apps") 
mysql_cursor = mysql.cursor() 

sqlStmt="UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 

mysql_cursor.execute(sqlStmt, record_ids) 
mysql.commit() 

Każda pomoc będzie doceniona!

Odpowiedz

18

try:

",".join(map(str, record_ids)) 

",".join(list_of_strings) dołącza listę ciąg oddzielając je przecinkami

jeśli masz listę numerów, map(str, list) będzie przekonwertować go do listy ciągów

+0

Dzięki, ten sam trick! – m0j0

2

Dalsze do podanych odpowiedzi, zwróć uwagę, że możesz chcieć w specjalnym przypadku pusta lista jako "where rec_id in()" jest niepoprawna SQL, więc dostaniesz błąd.

Należy również bardzo ostrożnie budować SQL ręcznie w ten sposób, zamiast używać tylko parametrów z automatycznym dopasowaniem. Dla listy liczb całkowitych będzie działać, ale jeśli masz do czynienia z ciągami otrzymanymi od użytkownika, w ten sposób otwierasz ogromną lukę SQL injection.

+0

+1 Proszę użyć zmiennych wiązania. http://stackoverflow.com/questions/1973/what-is-the-best-way-to-avoid-sql-injection-attacks –

+0

To będzie tylko odczyt danych z bazy danych i aktualizacja danych. Nigdy nie będzie korzystać z danych wprowadzanych z Internetu. – m0j0

+0

Ostrożnie: wiele danych w bazach danych jest ostatecznie wprowadzanych przez użytkowników. Nawet jeśli twoja sprawa jest całkowicie bezpieczna, niektóre późniejsze urządzenia z podobnym problemem mogą podjąć decyzję o skopiowaniu istniejącego kodu. Warto dbać o te rzeczy, nawet gdy jest to bezpieczne. Lepiej wzmacniać i wykazywać dobre nawyki niż złe. – Brian

1

zrobić rzeczy jak to (w celu zapewnienia używam powiązań):

sqlStmt=("UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 
    % ', '.join(['?' for n in record_ids])) 

mysql_cursor.execute(sqlStmt, record_ids) 
mysql.commit() 

To działa dla wszystkich dynamicznych list chcesz związać bez wychodzenia jesteś podatny na ataki SQL injection.

+0

Nie sądzę, aby znaki zapytania działały dla powiązań MySQL. – m0j0

+0

To jest wadą interfejsu API Pythona. Zrobiłem powyższe dla sqlite i postgres, ale to do kierowcy należy decyzja, jak działają wiązania. Ta sama zasada obowiązuje. Wygeneruj wiązania i podaj dane. – Dustin

0

Nieco inna alternatywa odpowiedź Dustina:

sqlStmt=("UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 
    % ', '.join(['?' * len(record_ids]))) 
+0

To nie rozwija się poprawnie, ale robi to: "," .join ("?" * Len (record_ids)) - Ja to lubię, choć czuje się lekko nie tak. – Dustin

0

Alternitavely korzystając zastąpić:

sqlStmt="UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in " + 
    record_ids.__str__().replace('[','(').replace(']',')')