自定义数据类型如何在SQLite中工作

时间:2016-09-24 20:54:43

标签: sqlite

以下SQL语句在SQLite中的作用是什么?

CREATE TABLE foo(id INTEGER PRIMARY KEY, time STRFTIME);

请注意,time列的STRFTIME类型未在documentation中列出。

我猜以下INSERT可以正常运行

sqlite> INSERT INTO foo (time) VALUES('text');
sqlite> SELECT * FROM foo;
1|text

因为这个:

  

3.1。柱亲和力的测定

     

列的亲和力由声明的类型决定   列,按照以下规则显示顺序:

     
      
  1. 如果声明的类型包含字符串" INT"然后它被分配   INTEGER亲和力。

  2.   
  3. 如果声明的列类型包含任何字符串" CHAR",   " CLOB",或" TEXT"然后该列具有TEXT亲和力。请注意   type VARCHAR包含字符串" CHAR"因此分配了TEXT   亲和力。

  4.   
  5. 如果列的声明类型包含字符串" BLOB"或者如果没有   指定了类型,然后该列具有关联BLOB。

  6.   
  7. 如果列的声明类型包含任何字符串" REAL",   " FLOA",或" DOUB"然后该列具有REAL亲和力。

  8.         

    5。否则,亲和力为NUMERIC

和此:

  

具有NUMERIC亲和力的列可能包含使用全部五个值的值   存储类。当文本数据插入NUMERIC列时,   文本的存储类转换为INTEGER或REAL(按顺序)   (如果这种转换是无损且可逆的)。对于   SQLite认为,TEXT和REAL存储类之间的转换   如果前15个转换为无损且可逆转   保留该数字的有效十进制数字。 如果   无法将TEXT无损转换为INTEGER或REAL   使用TEXT存储类存储该值。没有尝试   转换NULL或BLOB值

我是对的吗?

2 个答案:

答案 0 :(得分:1)

是; STRFTIMEFLUFFY BUNNIES具有完全相同的亲和力,即数字。

答案 1 :(得分:1)

如果要实现新类型,它仍然必须在内部存储在一个sqlite基元类型中。然后,您必须提供从python转换为sqlite的函数,反之亦然。

以下是要执行的步骤:

  • 使用sqlite3.register_adapter指定如何将python类型转换为sqlite。虽然您可以转换为sqlite内部/基本类型之一(text,integer,real,blob和null),但您应该使用TEXT转换回来(参见下一点)。
  • 使用sqlite3.register_converter指定如何将sqlite内部表示转换回python类型。
  • 调用connect()时,请指定detect_types=sqlite3.PARSE_DECLTYPES参数。
  • 创建表格时,请使用自定义类型名称。

注意:register_converter文档说您必须从bytestring转换。

以下是实现自定义“日期”类型的示例:

import sqlite3
from datetime import date

def date_to_str(d):   # for python to sqlite
  return '%04d%02d%02d' % ( d.year, d.month, d.day )
def str_to_date(s):   # for sqlite to python
  y=int(s[0:4])
  m=int(s[4:6])
  d=int(s[6:8])
  return date(y,m,d)

sqlite3.register_adapter(date,date_to_str)
sqlite3.register_converter('date',str_to_date)

WEEKDAYS = {
  0: "Mon", 1: "Tue", 2: "Wed", 3: "Thu", 4: "Fri", 5:"Sat",6:"Sun"
}
def test():
  s = sqlite3.connect('myfile.dat', detect_types=sqlite3.PARSE_DECLTYPES)
  c = s.cursor()
  c.execute('create table t1(id integer primary key, d1 date)')
  c.execute('insert into t1 values(?,?)', (1, date(2016,9,24)))
  c.execute('insert into t1 values(?,?)', (2, date(2000,1,1)))
  s.commit()
  for r_id, r_date in c.execute('select id,d1 from t1 order by d1'):
    print r_id, r_date, r_date.year, r_date.month, r_date.day, WEEKDAYS[r_date.weekday()]


if __name__ == '__main__':
  test()

当我输入答案时,我读了接受的答案,并意识到这不是你的问题。但是,如果这可以帮助其他人...