Я использовал django-эволюцию. Протесты включают:
Однако я нахожу, что пользовательские schema_evolution.py
приближаются удобный. Для работы вокруг проблемы цифрового отпечатка я предлагаю код как:
BEFORE = 'fv1:-436177719' # first fingerprint
BEFORE64 = 'fv1:-108578349625146375' # same, but on 64-bit Linux
AFTER = 'fv1:-2132605944'
AFTER64 = 'fv1:-3559032165562222486'
fingerprints = [
BEFORE, AFTER,
BEFORE64, AFTER64,
]
CHANGESQL = """
/* put your SQL code to make the changes here */
"""
evolutions = [
((BEFORE, AFTER), CHANGESQL),
((BEFORE64, AFTER64), CHANGESQL)
]
, Если бы у меня было больше цифровых отпечатков и изменений, я осуществил бы рефакторинг его. До тех пор создание его инструмент для очистки украло бы время разработки из чего-то еще.
РЕДАКТИРОВАНИЕ: , Учитывая, что я вручную создаю свои изменения так или иначе, я попробую dmigrations в следующий раз.
(defn run-sim [arr num-iters update-fn]
(if (zero? num-iters)
arr
(let [i (rand-int (count arr))
x (update-fn)]
(println "setting arr[" i "] to" x)
(recur (assoc arr i x) (dec num-iters) update-fn))))
user> (run-sim [1 2 3 4 5 6 7 8 9 10] 10 #(rand-int 1000))
setting arr[ 8 ] to 167
setting arr[ 4 ] to 977
setting arr[ 5 ] to 810
setting arr[ 5 ] to 165
setting arr[ 3 ] to 486
setting arr[ 1 ] to 382
setting arr[ 4 ] to 792
setting arr[ 8 ] to 478
setting arr[ 4 ] to 144
setting arr[ 7 ] to 416
[1 382 3 486 144 165 7 416 478 10]
Нет ничего постыдного в использовании массива Java, если он вам нужен. Особенно, если вам нужно двигаться быстро. Ограничьте изменение массива внутри вашей функции (клонируйте входной массив и, возможно, поработайте над этим), и никто не станет мудрее.
Дополнение к ответу Брайана: Если вам нужно больше скорости, вы также можете прибегнуть к переходным процессам.
(defn run-sim
[vektor num-iters update-fn]
(loop [vektor (transient vektor)
num-iters (int num-iters)]
(if (zero? num-iters)
(persistent! vektor)
(let [i (rand-int (count vektor))
x (update-fn)]
(recur (assoc! vektor i x) (dec num-iters))))))
Давайте сначала определим функцию, которая обновляет случайный индекс в векторе новым значением. Обратите внимание, что исходный вектор не изменяется, вместо этого возвращается новый вектор (с обновленным значением):
(defn f [xs]
(let [r (java.util.Random.)
i (.nextInt r (count xs))
b (.nextBoolean r)]
(assoc xs i ((if b inc dec) (xs i)))))
Эта функция выбирает индекс, а затем увеличивает или уменьшает значение этого индекса на 1. Вы, конечно, должны изменить эта функция под ваши нужды.
Тогда несложно скомпоновать эту функцию с собой столько раз, сколько вы хотите запускать симуляцию:
user=> ((apply comp (repeat 1000 f)) [0 0 0 0 0 0 0])
[7 -4 7 6 10 0 -6]
Clojure не победил ' t позволяет изменять значения, это немного более громоздко.
(def vec-ref (ref my-vector))
(dosync (set! vec-ref (assoc my-vector index value))
для просмотра значений в измененном векторе используйте @ vec-ref.
Могут быть отключены в деталях - я, к сожалению, не близок к REPL. Но это должно помочь вам начать.