Два приложения не согласны с sqllite3 DATEFIELDs - что правильно? - PullRequest
1 голос
/ 04 марта 2011

Я сталкиваюсь с несовместимостью при обработке sqllite3 DATEFIELD между Digikam (программное обеспечение для управления фотографиями) и Django (веб-среда Python) .Я столкнулся с проблемой, потому что я пытаюсь написать приложение Django, которое предоставит интерфейс веб-страницы для моей коллекции фотографий на основе моей базы данных Digikam.

База данных была создана Digikam, и все DATEFIELDS находятся в этомформат (с помощью браузера базы данных SQLite для просмотра таблиц):

**2011-02-06T19:06:28**

Когда Django сохраняет даты (используя поле DateTime Django), формат в базе данных:

**2011-03-04 00:24:07.013620**

Djangoдроссели, когда он встречает дату / время, созданные Digikam:

/usr/lib/python2.6/dist-packages/django/db/backends/util.py in typecast_date(s)
     58 
     59 def typecast_date(s):
---> 60     return s and datetime.date(*map(int, s.split('-'))) or None # returns None if s is null
     61 
     62 def typecast_time(s): # does NOT store time zone information

ValueError: invalid literal for int() with base 10: '03T15:53:14'

Итак, возникает несколько вопросов:

  1. Какой из этих форматов даты действителен?
  2. Разве sqllite не проверяет ввод даты и времени?
  3. Есть ли простой способ заставить Django счастливо читать даты в формате Digikam?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 04 марта 2011

Относительно 2): насколько я знаю, sqlite не выполняет никакой проверки ввода. Глядя на sqlite docs , я вижу это:

SQLite не имеет класса хранения отложить для хранения дат и / или раз. Вместо этого встроенная дата и Временные функции SQLite способны хранения даты и времени в текстовом формате, Значения REAL или INTEGER:

ТЕКСТ как строки ISO8601 ("ГГГГ-ММ-ДД" HH: MM: СС.ссс ")

.

...

Итак, из моего прочтения, Digikam не играет по (очень мягким) правилам sqlite. (Возможно, потому что то, что вы описываете, не было в голове у авторов, когда они создавали свою базу данных).

В зависимости от вашего рабочего процесса для этого есть несколько вариантов, которые я могу придумать, но ни один не очень удовлетворительный:

  • изменить код Digicam для вывода чего-то вроде формата TEXT для даты, который SQLite объявляет в своих документах.
  • изменить код Django для анализа этого формата даты.
  • создайте представление в вашей базе данных, используя одну из [манипуляций с датами] (http://www.sqlite.org/lang_datefunc.html) функции для преобразования этого столбца, и пусть django использует это представление

Первые два довольно сложны / сложны в обслуживании, третий кажется выполнимым без особых хлопот.

Последний обходной путь, если вы фактически не используете одну и ту же базу данных (но копию) для обоих приложений, - это написание простого сценария для преобразования этого столбца оптом. Не "красиво", но должно работать.

0 голосов
/ 01 мая 2011

Я поражен точно таким же разочарованием. В итоге я написал следующий патч для обезьян в моем models.py, который «решил» проблему для меня:

# -------------------------------------------------------------                                                       
# Monkeypatch date parser to be friendly with Digikam SQLite                                                          
# -------------------------------------------------------------                                                       

import django.db.backends.util                                                                                        
orig_typecast_date = django.db.backends.util.typecast_date                                                            
def monkeypatch_typecast_date(s):                                                                                     
    if s and 'T' in s:                                                                                                
        s = s[:s.find('T')]                                                                                           
    return orig_typecast_date(s)                                                                                      
django.db.backends.util.typecast_date = monkeypatch_typecast_date     
0 голосов
/ 04 марта 2011

Оба формата являются разумными представлениями даты. SQLite не имеет собственного типа datetime, но имеет ряд функций для работы с датами / временем, хранящимися в виде вещественных чисел, целых или текстовых объектов (см. http://www.sqlite.org/datatype3.html).

Учитывая, что Django и Digicam решили обрабатывать даты в разных форматах, ваш лучший маршрут, вероятно, состоит в том, чтобы написать новый тип поля модели, который может обрабатывать формат даты, используемый Digikam (http://docs.djangoproject.com/en/dev/howto/custom-model-fields/). Если все, что вы делаете, это читаете Digikam dtabase, это довольно просто - вам просто нужно немного кодировать, чтобы преобразовать представление в объект Python Datetime, что вы, вероятно, сможете сделать с помощью функции datetime.strptime Python (http://docs.python.org/library/datetime.html#datetime.datetime.strptime).

...