Я хотел бы повторить вычисление по столбцу значений в базе данных MySQL. Мне было интересно, есть ли в Django какие-либо встроенные функции для этого. Раньше я просто использовал следующее для хранения каждого столбца в виде списка кортежей с именем table_column:

import MySQLdb
import sys

try:
    conn = MySQLdb.connect (host = "localhost",
                            user = "user",
                            passwd="passwd",
                            db="db")
except MySQLdb.Error, e:
    print "Error %d: %s" % (e.args[0], e.args[1])
    sys.exit (1)

cursor = conn.cursor()

for table in ['foo', 'bar']:
    for column in ['foobar1', 'foobar2']:
        cursor.execute('select %s from %s' % (column, table))
        exec "%s_%s = cursor.fetchall()" % (table, column)

cursor.close()

conn.commit()
conn.close()

Есть ли в Django какие-либо функции для более удобного перебора значений столбца в таблице базы данных? Я имею дело с миллионами строк, поэтому важна скорость выполнения.

[решено] Всем спасибо. Я использовал встроенный итератор в сочетании с вызовом values_list () для оптимизации производительности. Обратите внимание, что вызов values ​​() вернет dicts, которые медленно перебираются, тогда как values_list () возвращает гораздо более быстрые кортежи. Так, например, если я хочу перебрать каждую строку столбца foobar1 в таблице foo, я могу получить итератор следующим образом:

foobar1_iterator = foo.objects.values_list('foobar1').iterator()

Предположим, я хочу перебрать i, чтобы получить список всех значений строки foobar1. Тогда просто сделайте это:

foobar1_list = [i for i in foobar1_iterator]
1
curious 7 Апр 2010 в 23:30

3 ответа

Лучший ответ

Загляните в документы Django только для () и итератора ():

http://docs.djangoproject.com/en/1.1/ref/models/querysets/#only-fields

http://docs.djangoproject.com/en/1.1/ref/models/querysets/#iterator

1
Yaroslav 8 Апр 2010 в 00:17

Микрооптимализация базы данных не является сильной стороной Django ORM. Однако, когда скорость так важна, мне интересно, правильный ли способ сделать это с помощью exec.

В любом случае, вы пишете «перебирать значения столбца», это означает, что у вас есть несколько значений в одном столбце, разделенных разделителем (не видно в вашем коде)?

Тогда просто

for value in modelinstalnce.column.split('seprator'):
    print 'whatever'

Что касается подключения, то лучше использовать

from django.db import connection

Вместо того, чтобы делать это вручную.

Что касается пар, я бы сделал что-то вроде:

pairs = []

for model in (MyModel, MyModel2,):
    for field in model.field_names:
        pairs.append((field, getattr(model, field))
2
Almad 7 Апр 2010 в 23:49
from django.db.models.loading import get_model
app_name = 'your_app_name'
for model_name in ['foo','bar']:
    model = get_model(app_name, model_name)
    model_values = model.objects.values('foorbar1','foobar2') # this is a ValuesQuerySet. 
                                                              # you can run your computation on it, 
                                                              # or store the values somewhere.
1
Ofri Raviv 7 Апр 2010 в 23:46