两个应用程序在sqlite3 DATE FIELDs上不一致 - 这是正确的吗?

时间:2011-03-04 06:44:12

标签: django sqlite datetime

我在处理 Digikam(照片管理软件) Django(python web框架)之间的 sqllite3 DATEFIELD 时遇到了不兼容的问题。我遇到了这个问题,因为我正在尝试编写一个Django应用程序,它将根据我的Digikam数据库为我的照片集提供一个网页界面。

数据库由Digikam创建,所有DATEFIELDS都采用这种格式(使用SQLite数据库浏览器查看表格):

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

当Django存储日期时(使用Django DateTime字段),数据库中的格式为:

**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格式的日期?
  4. 谢谢!

3 个答案:

答案 0 :(得分:0)

两种格式都是合理的日期表示。 SQLite没有本机日期时间类型,而是有许多函数用于处理存储为实数,整数或文本对象的日期/时间(请参阅http://www.sqlite.org/datatype3.html)。

鉴于Django和Digicam选择以不同格式处理日期,您最好的路线可能是编写一个新的模型字段类型,可以处理Digikam使用的日期格式(http://docs.djangoproject.com/en/开发/ HOWTO /自定义模型字段/)。如果您所做的只是阅读Digikam dtabase,这非常简单 - 您只需要编写一些代码就可以将表示转换为Python Datetime对象,您可能可以使用Python的{ {1}}函数(http://docs.python.org/library/datetime.html#datetime.datetime.strptime)。

答案 1 :(得分:0)

关于2):据我所知,sqlite没有做任何输入验证。看sqlite docs,我看到了:

  

SQLite没有存储类   留出用于存储日期和/或   倍。相反,内置的日期和   SQLite的时间函数是有能力的   将日期和时间存储为TEXT,   REAL或INTEGER值:

     

TEXT as ISO8601 strings(“YYYY-MM-DD   HH:MM:SS.SSS“)

     

...

所以从我的阅读来看,Digikam是那个没有玩(非常软)sqlite规则的人。 (可能是因为你所描述的内容并非作者在构建数据库时的想法。)

根据您的工作流程,我可以想到几个选项,没有一个非常令人满意:

  • 修改Digicam代码,输出类似于SQLite在其文档中宣传的日期的TEXT格式。
  • 修改Django代码以解析该日期格式。
  • 使用[日期操作](http://www.sqlite.org/lang_datefunc.html)函数之一在数据库中创建一个视图来转换该列,并让django使用该视图

前两个相当复杂/难以维护,第三个似乎可行,没有太多麻烦。

最后一种解决方法,如果你实际上并没有为这两个应用程序使用相同的数据库(但是副本),那就是编写一个简单的脚本来转换该列。不是“漂亮”,但应该有用。

答案 2 :(得分:0)

我完全同样沮丧。我最终在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