2010-11-25 24 views
12

Python ve SQLite kullanarak tarih depolama/alma ile ilgili tasarım sorunları yaşıyorum.SQLite tarih depolama ve dönüştürme

Bir SQLite tarih sütununun tarihlerini metin olarak ISO biçiminde (ör. '2010-05-25') depoladığını anlıyorum. o masaya yazma-geri verilerine geldiğinde ben (web sayfasında örn.) bir İngiliz tarihini görüntülemek Yani ben Ancak

datetime.datetime.strptime(mydate,'%Y-%m-%d').strftime('%d/%m/%Y') 

kullanarak tarih dönüştürmek , SQLite çok bağışlayıcı ve olduğu oldukça tarihi alanında '25/06/2003' saklamak için mutlu, ancak bu değil idealdir çünkü

  • aynı sütunda tarih biçimleri karışımı ile sol olabilir

    ,

  • olduğunu

    SQLite'nin tarih işlevleri yalnızca ISO formatıyla çalışır.

Bu yüzden işlemekle önce geri ISO biçimine tarih dizesi dönüştürmek gerekir, ama sonra bütün tarih alanlarında yazılı ve gerekirse ISO dönüştürür edilecek ilgili verileri denetleyen bir genel işlevi gerekir. Bu bana biraz sıkıcı geliyor ama belki de kaçınılmaz.

Daha basit çözümler var mı? Tarih alanını 10 karakter alanına değiştirmek ve tablo boyunca 'dd/mm/yyyy' depolamak daha kolay olur mu? Bu şekilde tablodan okurken veya yazarken dönüşümü gereklidir ve herhangi bir tarih-aritmetiği gerçekleştirmem gerekirse datetime() işlevlerini kullanabilirim.

Diğer geliştiriciler bu sorunu nasıl aştı? Herhangi bir yardım takdir edilecektir. Kayıt için Python 3.1 ile SQLite3 kullanıyorum. Eğer sqlite3.connect yılında detect_types=sqlite3.PARSE_DECLTYPES ayarlarsanız

cevap

14

, ardından bağlantısı veritabanından veri çizerken Python veri türleri için sqlite veri türlerini dönüştürmek için çalışacağız.

Bu yana çok iyi bir şey olduğunu onun ardından datetime.datetime.strptime veya dateutil.parser.parse ile ayrıştırmak zorunda rastgele tarih benzeri dizeleri daha datetime nesnelerle çalışmak için çok daha güzel.

Maalesef detect_types kullanarak TARİH veri olarak dizeleri kabul gelen sqlite durmaz, ama sen çalıştığınızda bir hata alıyorum o dışında bazı formatta eklenmesi durumunda (veritabanından veri çekecek YYYY-AA-GG) bağlantı datetime.date nesnesine dönüştürmek için başarısız olur, çünkü:

conn=sqlite3.connect(':memory:',detect_types=sqlite3.PARSE_DECLTYPES) 
cur=conn.cursor() 
cur.execute('CREATE TABLE foo(bar DATE)') 
# Unfortunately, this is still accepted by sqlite 
cur.execute("INSERT INTO foo(bar) VALUES (?)",('25/06/2003',)) 

# But you won't be able to draw the data out later because parsing will fail 
try: 
    cur.execute("SELECT * FROM foo") 
except ValueError as err: 
    print(err) 
    # invalid literal for int() with base 10: '25/06/2003' 
    conn.rollback() 

Ama en azından hata, bir için bir dize ekledikten konusunda sizi uyaracaktır DATE tarihini gerçekten girmeniz gerektiğinde.tarih nesneler:

cur.execute("INSERT INTO foo(bar) VALUES (?)",(datetime.date(2003,6,25),)) 
cur.execute("SELECT ALL * FROM foo") 
data=cur.fetchall() 
data=zip(*data)[0] 
print(data) 
# (datetime.date(2003, 6, 25),) 

Ayrıca sürece YYYY-AA-GG biçimini kullanın olarak TARİH veri olarak dizeleri ekleyebilirsiniz. Eğer bir dize takılı halde, bir datetime.date nesne olarak geri geliyor dikkat edin: çizerken

cur.execute("INSERT INTO foo(bar) VALUES (?)",('2003-06-25',)) 
cur.execute("SELECT ALL * FROM foo") 
data=cur.fetchall() 
data=zip(*data)[0] 
print(data) 
# (datetime.date(2003, 6, 25), datetime.date(2003, 6, 25)) 

Eğer DATE alana sadece datetime.date nesneleri ekleme hakkında disiplinli Yani eğer, o zaman daha sonra hiçbir sorun olacak veri çıkışı.

Kullanıcılarınız çeşitli biçimlerde giriş tarihi verileriyse, dateutil.parser.parse'a bakın. Bu çeşitli dizeleri datetime.datetime nesnesine dönüştürmenize yardımcı olabilir.

+0

Teşekkürler unutbu - tarih nesneleri gibi görünüyor. Saygılarımızla. –

5

SQLite'nin yerel bir tarih/saat türü olmadığını unutmayın. @unutbu'nun yanıtladığı gibi, pysqlite/sqlite3 modülünü tahmin etmeye çalışın (ve gerçekten bir tahmin olduğunu unutmayın). SQL ifadeleri kolayca karıştıracaktır.

SQLite, çeşitli tarih saat işlevlerine sahiptir ve çeşitli dizelerle, hem unixepoch hem de julian biçimindeki sayılarla çalışabilir ve dönüştürmeler yapabilir. belgelere bakın: Sen daha rahat yerine Python içine değerleri ithal ve bunu yapmak için Python kütüphanelerini kullanarak gerek tarih/saat işi yapmak için SQLite almak için bulabilirsiniz

http://www.sqlite.org/lang_datefunc.html

. Örneğin, bu dize değerinin bulunmasını gerektiren belirli bir uzunluk vb. Gibi SQL tablo tanımında kısıtlamalar koyabileceğinizi unutmayın.

+0

Cevap için teşekkürler Roger. Bu SQLite tarih fonksiyonlarını kontrol edeceğim. Saygılarımızla. –

İlgili konular