2008-12-29 6 views
-1

J'écris un programme au moment où il interagit avec une base de données MySQL et que j'ai un problème. Comme vous pouvez le voir, j'ai écrit une requête qui cherchera des produits dans la table des produits qui correspondent au code à barres que l'utilisateur a entré. Si le code à barres saisi par l'utilisateur se trouve dans la table des produits, je souhaite augmenter le champ 'quantité' de 1 dans la table des stocks où le produit correspondant à l'entrée du code à barres est le même que le produit dans la table des stocks.Affectation d'une 'boucle for' à une variable dans un programme python

Comme vous pouvez le voir, j'ai essayé d'assigner une variable à la boucle for pour essayer de la faire fonctionner mais ça ne marche pas. Quelqu'un at-il une idée de la façon de le faire?

import MySQLdb 

def look_up_product(): 
    db = MySQLdb.connect(host='localhost', user = 'root', passwd='$$', db='fillmyfridge') 
    cursor = db.cursor (MySQLdb.cursors.DictCursor) 
    user_input=raw_input('please enter the product barcode that you wish to checkin to the fridge: \n') 
    if cursor.execute("""select * from products where product = %s""", (user_input)): 
     db.commit() 
     result_set = cursor.fetchall() 
     #i want here to assign a variable to this for loop and the line below = for product in result_set: 
      print "%s" % (row["product"]) 
     cursor.execute('update stocks set amount = amount + 1 where product = %s', (#here i want the result of the for loop)) 
     db.commit() 
    else: 
     print 'no not in products table' 

merci mille fois.

+1

Cette question est impénétrable. Qu'essayez-vous de faire? Quelle est la signification de "assigner une variable à cette boucle et à la ligne ci-dessous"? Quelles données avez-vous dans result_set qui nécessite une boucle? –

Répondre

0

Vous attendez donc une seule ligne? Si oui, essayez ceci:

row = cursor.fetchone() 
print row["product"] 
cursor.execute('update stocks set amount = amount + 1 where product = %s', row["product"]) 
0

Je ne sais pas comment vous obtenez un identifiant de ligne de la valeur extraite de produits de table. Je recommande de spécifier explicitement les colonnes nécessaires et de ne pas utiliser l'idiome select * from.

J'introduit la fonction d'aide pour la recherche d'identifiant pour rendre le code plus lisible:

def getAnIdFromValue(someValueTuple): 
    '''This function retrieves some table row identifier from a row tuple''' 
    returns someValueTuple[0] 

Je vais essayer le corps de la fonction suivante si plusieurs lignes sont attendus:

db = MySQLdb.connect(...) 
cursor = db.cursor() 
ids = [] 
cursor.execute("""select * from products where product = %s""", (user_input)) 
for value in cursor.fetchall(): 
    #value is a tuple. len(value) == number of columns in products table 
    ids.append(getAnIdFromValue(value)) 
if len(ids): 
    cursor.executemany("update stocks set amount = amount + 1 where product =%s", tuple(ids)) 
    db.commit() 
else: 
    print 'no not in products table' 
0

Je pense que vous besoin de mettre en retrait la ligne "mise à jour des stocks ..." afin qu'elle soit à l'intérieur de la boucle for.

+0

En fait, c'est le moyen sûr d'utiliser user_input, puisque cursor.execute va citer et échapper la valeur lors de son ajout à la requête.Il n'y a pas de risque d'injection SQL ici. –

+0

Je vois, j'ai vu le "% s" là où je me suis habituellement "?" et a sauté. =) – PEZ

0

Là-bas. J'ai également corrigé une virgule qui vous manquait sur la première ligne cursor.execute.

import MySQLdb 

def look_up_product(): 
    db = MySQLdb.connect(host='localhost', user = 'root', 
         passwd='$$', db='fillmyfridge') 
    cursor = db.cursor (MySQLdb.cursors.DictCursor) 
    user_input=raw_input('please enter the product barcode ' 
         'that you wish to checkin to the fridge: \n') 
    cursor.execute("""select * from products where product = %s""", 
        (user_input,)) 
    for row in iter(cursor.fetchone, None): 
     print row["product"] 
     cursor.execute('update stocks set amount = amount + 1' 
         ' where product = %s', (row["product"],)) 
    db.commit() 

Bien sûr, vous pouvez toujours utiliser sqlalchemy à la place:

import sqlalchemy as sa 
import sqlalchemy.orm 

# Prepare high-level objects: 
class Product(object): pass 
engine = sa.create_engine('mysql://root:[email protected]/fillmyfridge') 
session = sa.orm.create_session(bind=engine) 
product_table = sa.Table('products', sa.MetaData(), autoload=True) 
sqlalchemy.orm.mapper(Product, product_table) 

def look_up_product(): 
    user_input=raw_input('please enter the product barcode ' 
         'that you wish to checkin to the fridge: \n') 
    for prod in session.query(Product).filter(Product.product == user_input): 
     print prod.product 
     # Here's the nicety: to update just change the object directly: 
     prod.ammount = prod.ammount + 1 
    session.flush() 
    session.commit() 
1

La réponse dépend de ce que vous entendez par « affecter une variable à une boucle. » Cette formulation est déroutante car une boucle for est un outil pour contrôler le flux d'exécution - elle n'est normalement pas considérée comme ayant une valeur. Mais je pense que je sais ce que tu veux dire. Chaque fois que la boucle s'exécute, elle exécute print "%s" % (row["product"]). Je devine que vous voulez stocker toutes les chaînes que cela fait comme la boucle fonctionne. Je vais aussi deviner que vous vouliez dire row[product] et non row["product"], parce que ce dernier sera le même pour toute la boucle. Ensuite, vous pouvez le faire:

mylist = [] 
for product in result_set: 
    mylist.append("%s" % (row[product],)) 

Notez que l'opération% fonctionne même si vous n'êtes pas l'impression de la chaîne plus - ce qui est une surprise pour les gens qui viennent de C. Vous pouvez également utiliser compréhensions liste python pour faire cet événement plus succinct:

mylist = ["%s" % (row[product],) for product in result_set] 
Questions connexes