Ваш вопрос заключается в том, как обработать этот тип запроса или ошибки. Итак, вот мое предложение общей стратегии.
Сначала сделай свою домашнюю работу. Например, вы можете легко найти этот прошлый вопрос . Если вы уже пробовали способ, но обнаружили, что он не работает, вы должны были описать, что вы сделали, а что не сработало в вашем вопросе.
Теперь, я предполагаю, что вы можете воспроизвести случай или, по крайней мере, вы можете ожидать, что столкнетесь с той же проблемой в ближайшем будущем (или вы можете подождать до тех пор), чтобы у вас было больше шансов определить проблему в следующий раз. , Если вы знаете, какие параметры вызвали ошибку, я думаю, вы можете воспроизвести случай в вашей среде разработки. Однако, если нет, то это более сложно определить - это сильно зависит от того, сколько информации об ошибке и входных данных у вас есть, и какую среду разработки вы можете использовать, и мой ответ не охватывает этот случай.
Первая цель должна состоять в том, чтобы определить, какая именно команда (метод) в вашем коде вызвала ошибку. Это произошло только внутри Rails или ваша БД вызвала ошибку? В вашем конкретном случае это произошло в Step.find_by
или @step.update
или еще? Что такое steps_params
? Это похоже на метод, который вы определили. Вы уверены, что steps_params
работает как положено? (Вы можете быть уверены, но мы не знаем…)
Удобный способ выяснить это - просто вставить logger.debug
(или logger.error
) и т. Д. До и после каждого предложения. При этом рекомендуется в некоторых случаях разбивать предложение на более мелкие единицы. Например, steps_params
и update()
должны быть разделены, например (в простейшем случае),
logger.debug 'Before steps_params'
res_steps_params = steps_params
logger.debug 'Before update'
res_update = @step.update(res_steps_params)
logger.debug 'Before if'
if res_update
# ……
Очевидно, что вы можете (и, возможно, должны) регистрировать более подробную информацию, такую как, [119 ], и вы также можете заключить деталь с предложением begin
- rescue
, чтобы вы могли получить подробную информацию об исключении и записать его в журнал. Также я могу порекомендовать разделить update
на 2 части - замены и save
- чтобы точно определить, какое действие и параметр вызывают проблему.
Как только вы выяснили, какая из БД или Rails или что-то раньше (например, HTTP-сервер или клиент-браузер) виновата, а какой параметр вызывает проблему, вы можете перейти к следующему этапу. Сообщение об ошибке предполагает, что это проблема кодировки символов. Является ли кодировка символов строки недопустимой (как UTF-8) или неправильно распознанной Rails (что может быть не ошибкой Rails, а клиента), или неправильно распознана БД?
Где бы ни находилась проблема, обычно (хотя и не всегда!) Можно исправить или обойти проблемы кодировки символов с помощью Ruby (Rails). Методы Ruby из , String#encode
, , , String#encoding
, и String#force_encoding
были бы полезны для диагностики и, возможно, решения проблемы.
В качестве дополнительного примечания может быть полезно, если возможно, в вашей среде, просмотреть файл журнала вашей БД (PostgreSQL?), Чтобы выяснить, какой запрос, переданный из Rails в БД, вызвал проблему (если запрос действительно был перешел к ним!). В качестве альтернативы, Rails Gem SQL Query Tracker может быть полезен для того, чтобы узнать, какие запросы создает ваше приложение Rails (хотя я никогда не использовал его и поэтому не могу много рассказать.)
В конце В тот день, когда код ведет себя странным образом, я боюсь, что только верный способ решить - сузить проблемный пункт или параметр шаг за шагом. Удачи!
Остерегайтесь использования строковой интерполяции для запросов SQL, поскольку она не будет корректно экранировать входные параметры и оставит ваше приложение открытым для уязвимостей внедрения SQL. Разница может показаться тривиальной, но на самом деле она огромна .
c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2))
c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2))
Это добавляет путаницу к тому, что модификаторы используются для привязки параметров в операторе SQL различается между различными реализациями API БД и тем, что клиентская библиотека mysql использует синтаксис стиля printf
вместо более распространенного «?» маркер (используется, например, python-sqlite
).
У вас есть несколько доступных вариантов. Вы захотите освоиться с итерполяцией строки Python. Какой термин вы могли бы более успешно искать в будущем, когда хотите узнать что-то вроде этого.
Лучше для запросов:
some_dictionary_with_the_data = {
'name': 'awesome song',
'artist': 'some band',
etc...
}
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)
""", some_dictionary_with_the_data)
Учитывая, что у вас, вероятно, уже есть все ваши данные в объекте или словаре, второй формат подойдет вам лучше. Также отстойно, что приходится подсчитывать «% s» появления в строке, когда вам нужно вернуться и обновить этот метод через год:)
Связанные документы дают следующий пример:
cursor.execute ("""
UPDATE animal SET name = %s
WHERE name = %s
""", ("snake", "turtle"))
print "Number of rows updated: %d" % cursor.rowcount
Итак, вы просто нужно адаптировать это к вашему собственному коду - пример:
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(%s, %s, %s, %s, %s, %s)
""", (var1, var2, var3, var4, var5, var6))
(Если SongLength является числовым, вам может потребоваться использовать% d вместо% s).