久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

13.13 sqlite3 -- DB-API 2.0 SQLite數據庫接口[Pytho...

 weicat 2010-05-22
SQLite是一個提供輕量級的基于磁盤的數據庫的C語言庫,,它不需要一個獨立的服務進程,,并且允許你使用一種非標準的SQL查詢語言來訪問數據庫,。其他程序也可以使用SQLite來管理內部數據存儲,。你也可以使用SQLite來構建應用程序原型,,然后把代碼遷移到一個更大的數據庫,,比如PostgreSQL或者Oracle,。
pysqlite是Gerhard Haring寫的,提供一個與PEP 249描述的DB-API 2.0規(guī)格說明書兼容的SQL接口,。
要使用這個模塊,,你必須現創(chuàng)建一個代表數據庫的連接對象(Connection object)。如下的數據將被存儲在/tmp/example文件中:
conn = sqlite2.connect('/tmp/example')
你還可以提供一個特殊的名稱":memory:"在內存中來創(chuàng)建一個數據庫,。
一旦你建立了一個連接(Connection),,你就可以創(chuàng)建一個游標對象(Cursor object),并且調用它的execute()方法來執(zhí)行SQL命令:
 
c = conn.cursor()
 
#Creat table
c.execute('''creat table stocks
(data text, trans text, symbol text,
qty real, price real)''')
 
#Insert a row of data
c.execute('''insert into stocks
values('2006-01-05','BUY','RHAT',100,35.14)''')
 
通常你的SQL操作會用到你的Python程序中的變量的值,。你不應該使用Python的字符串操作符來集合你的查詢,,因為這樣是不安全的;它使你的程序容易首道SQL注入攻擊,。
替代方法是使用DB-API的參數交換,。在你需要使用一個變量的時候,使用"?"作為一個占位符,然后提供一個包含變量的元組作為油表對象的execute()方法的第二個參數,。(其他的數據庫模塊可能使用不同的占位符,,比如"%s"或者":1"。)例如:
 
#Never do this -- insecure!
symbol = 'IBM'
c.execute('''... where symbol = '%s' % symbol)
 
#Do this instead
t = (symbol,)
c.execute('select * from stocks where symbol=?', t)
 
#Larger example
for t in (('2006-03-28','BUY','IBM',1000,45.00),
('2006-04-05','BUY','MSOFT',1000,72.00),
('2006-04-06','SELL','IBM',500,53.00),
):
c.execute('insert into stocks values (?,?,?,?,?)', t)
 
為了在執(zhí)行一個select語句后返回數據,,你既可以把游標作為一個迭代器來對待,,調用游標對象的fetchone()方法來返回一個單一的匹配行,也可以調用fetchall()方法得到一個所有匹配行的列表,。
下面這個例子使用了迭代器的方式:
 
>>> c = conn.cursor()
>>> c.execute('select * from stocks order by price')
>>> for row in c:
...     print row
...    
(u'2006-01-05', u'BUY', u'RHAT', 100, 35.140000000000001)
(u'2006-03-28', u'BUY', u'IBM', 1000, 45.0)
(u'2006-04-06', u'SELL', u'IBM', 500, 53.0)
(u'2006-04-05', u'BUY', u'MSOFT', 1000, 72.0)
>>>
 
See Also:
pysqlite的網站,。
SQLite的網站;相關文檔描述了語法以及對其支持的可愛的SQL的可用的數據類型,。
PEP 249, Database API Specification 2.0
Marc-André Lemburg寫的PEP,。
 
13.13.1 模塊函數和常量
PARSE_DECLTYPES
這個常量是用來作為connect函數的參數detect_types的值使用的。
設置它使sqlite3模塊解析返回的每一列的聲明類型,。他會解析出聲明類型中的第一個詞,,i. e. 對于'integer primary key',將會解析出'integer',。然后對于這一列,,他會在轉換字典中查找并且使用對這種類型注冊的轉換函數。注意:轉換器的名稱是大小寫敏感的,!
PARSE_COLNAMES
這個常量是用來作為connect函數的參數detect_types的值使用的,。
設置它使SQLite接口解析返回的每一列的列名字。他會在其中查找一個這樣書寫的字符串[mytype],,然后將‘mytype’作為這一列的類型,。他將嘗試在轉換字典中查找‘mytype’的入口,然后使用在字典中找到的轉換函數來返回值,。在cursor.description中找到的名字只是這個列的第一個字,,i. e. 如果你在SQL中使用這樣的語句:'as "x [datetime]"',那么將會解析出直到列名字中第一個空格出現時的任何字符——這個列的名字只是一個簡單的'x',。
connect(database[,timeout,isolation_level,detect_types,factory])
打開一個到SQLite數據庫文件database的連接,。你可以使用':memory:'來打開一個駐留在內存中而不是在磁盤上的數據庫連接。
當一個數據庫被多重連接時(when a database is accessed by multiple connections),,并且有一個進程更改了數據庫,,這個SQLite數據庫將會被鎖住直到交易被執(zhí)行。timeout參數指定這個連接在拋出一個異常之前等待的時間,。默認的timeout參數是5.0(5秒鐘),。
對于isolation_level參數,,請查看在13.13.2中描述的連接對象(Connection objects)的isolation_level屬性,。
SQLite本身只支持TEXT,INTEGER,FLOAT,BLOB和NULL類型。如果你希望使用其他類型,你需要添加自己的支持,。detect_types參數,,以及使用定制的利用模塊級的register_converter函數注冊的converters,可以讓你很容易實現它,。
detect_types默認為0(i. e. off, 沒有類型檢測),,你可以設置其為PARSE_DECLTYPES和PARSE_COLNAMES的任意組合來將類型檢測打開。
sqlite3默認模塊使用其Connection類來實現connection調用,。然而,,你可以編寫Connection類的一個子類,然后將你的類提供給factory參數來使用你自己的類建立連接,。
詳細信息請參閱本手冊的 13.13.4 章節(jié),。
 
register_converter(typename,callable)
注冊一個轉換器(callable)來將數據庫中的字節(jié)串轉換為一個Python類型。對于數據庫中的所有typename類型的數據,,這個轉換器都將被調用,。Confer the parameter detect_types of the connect function for how the type detection works.注意:typename和你的查詢中的類型名字的大小寫必須匹配。
register_adapter(type,callable)
注冊一個轉換器來將Python中的type類型轉換為SQLite支持的一種類型,。轉換器只callable接受一個單一的Python值作為參數,,也必須返回這些類型中的一個值:int, long, float, str(UTF-8 encoded),unicode代碼或字節(jié)流,。
complete_statement(sql)
返回True如果字符串sql是一個或多個用分號結束的SQL語句,。它不能識別出錯誤,如果SQL語句在語法上是正確的,,僅僅是在語義上不完整,,但是語句是以分號結束的。
者可以用來構建一個SQLite的解釋器,,就如下面的例子一樣:
#A minimal SQLite shell for experiments
 
import sqlite3
 
con = sqlite3.connect(":memory:")
con.isolation_level = None
cur = con.cursor()
 
buffer = ""
print "Enter your SQL commands to execute in sqlite3."
print "Enter a blank line to exit."
 
while True:
  line = raw_input()
  if line == "":
      break
  buffer += line
  if sqlite3.complete_statement(buffer):
      try:
          buffer = buffer.strip()
          cur.execute(buffer)
 
          if buffer.lstrip().upper().startswith("SELECT"):
              print cur.fetchall()
      except sqlite3.Error, e:
          print "An error occurred:", e.args[0]
      buffer = ""
 
con.close()
 
enable_callback_tracebacks(flag)
默認情況下,,在用戶定義的functions,aggregates,converters,authorizer等中你不會得到任何跟蹤信息。如果你想要調試它們,,你就可以用True作為flag參數的值來調用這個函數,。之后,你就可以在sys.stderr中得到從回調中返回的跟蹤信息,。使用False來再次關閉這個功能,。
13.13.2 連接對象(Connection Objects)
一個連接實例具有以下屬性和方法:
isolation_level
得到或設置當前的隔離級別(isolation level)。設置為None使用自動模式,,或"DEFERRED","IMMEDIATE"或"EXLUSIVE",。更具體的說明請參考13.13.5章中的"Controlling Transactions"。
cursor([cursorClass])
cursor方法接受一個單一的cursorClass參數,。如果這個參數被提供,,則必須是一個擴展了sqlite3.Cursor類的定制cursor類,。
execute(sql,[parameters])
這是一個非標準的,通過調用cursor方法創(chuàng)建一個中間cursor對象的快捷方式,,然后使用給出的參數調用cursor的execute方法,。
executemany(sql,[parameters])
這是一個非標準的,通過調用cursor方法創(chuàng)建一個中間cursor對象的快捷方式,,然后使用給出的參數調用cursor的executemany方法,。
executescript(sql_script)
這是一個非標準的,通過調用cursor方法創(chuàng)建一個中間cursor對象的快捷方式,,然后使用給出的參數調用cursor的executescript方法,。
creat_function(name,num_params,func)
創(chuàng)建一個用戶定義的函數,創(chuàng)建以后你可以在SQL語句中通過name名字使用,,num_params是這個函數接受的參數的數量,,func是一個作為SQL函數的Python調用器。
這個函數返回SQLite支持的任意類型:unicode,str,int,long,float,buffer和None,。
Example:
 
import sqlite3
import md5
def md5sum(t):
  return md5.md5(t).hexdigest()
 
con = sqlite3.connect(":memory:")
con.creat_function("md5",1,md5sum)
cur = con.cursor()
cur.execute("select mdt(?)", ("foo",))
print cur.getchone()[0]
 
creat_aggregate(name,num_params,aggregate_class)
創(chuàng)建一個用戶定義的聚合函數,。
一個聚合類必須提供一個step方法,它接受參數的數量num_params,,和一個finalize方法,,它返回最終的聚合結果。
finalize方法可以返回SQLite支持的任何類型:unicode,str,int,long,float,buffer和None,。
Example:
 
import sqlite3
 
class MySum:
  def __init__(self):
      self.count = 0
 
  def step(self, value):
      self.count += value
 
  def finalize(self):
      return self.count
 
con = sqlite3.connect(":memory:")
con.creat_aggregate("mysum", 1, MySum)
cur = con.cursor()
cur.execute("create table test(i)")
cru.execute("insert into test(i) values (1)")
cru.execute("insert into test(i) values (2)")
cur.execute("select mysum(i) from test")
print cur.fetchone()[0]
 
creat_collation(name, callable)
使用指定的name和callable創(chuàng)建一個校對,。調用器會被傳入兩個字符串參數。它應該返回-1,,如果第一個排序比第二個低,,返回0,如果兩個排序一致,,返回1,,如果第一個排序比第二個高。需要指出的是,,這個操作控制著排序(ORDER BY in SQL),,因此,你的比較不會影響其他SQL操作,。
注意:調用器將會按照Python的字節(jié)碼來接受參數,,這些參數通常的編碼是UTF-8。
下面的例子顯示了一個定制的對"the wrong way"進行排序的校對:
 
import sqlite3
 
def collate_reverse(string1, string2):
  return -cmp(string1, string2)
 
con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)
 
cur = con.cursor()
cur.execute("creat table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",),("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
  print row
con.close()
 
如果要刪除一個校對,,用None作為調用器來調用create_collation:
con.create_collation("reverse", None)
interrupt()
你可以從另一個線程中調用這個方法來中斷一個連接上可能進行的任何查詢操作,。查詢操作將會中斷,查詢的調用者將會得到一個異常,。
set_authorizer(authorizer_callback)
這個動作注冊一個調用器,。在每一次嘗試訪問數據庫中的一個表中的一列時,,這個調用器都將會被調用。調用器應該返回SQLITE_OK,,如果訪問被允許,返回SQLITE_DENY,,如果整個SQL語句因為錯誤而應該被中斷,,返回SQLITE_IGNORE,如果這一列應該作為NULL值來對待,。這些實例在sqlite3模塊中可用,。
調用器的第一個參數表明什么類型的操作要進行審定。第二個參數和第三個參數根據第一個參數,,會使參數或者None,。如果可用的話,第四個參數是數據庫的名字("main","temp"等等),。第五個參數是對試圖進行的訪問負責的最內的(inner-most)觸發(fā)器的名字或者視圖,,或者為None如果這個訪問直接來自于SQL代碼。
關于第一個參數的可能的取值,,以及依賴于第一個參數的第二個和第三個參數的含義,,請參閱SQLite的文檔。所有的必須的常量在sqlite3模塊中都是可用的,。
row_factory
你可以將這個屬性改變?yōu)橐粋€調用器的名字,,這個調用器接受一個游標和一行的元組,返回計算后的行,。這樣,,你可以實現返回結果的更高級的方法,比如,,返回一個任然可以通過名字訪問列的對象,。
Example:
 
import sqlite3
 
def dict_factory(cursor, row):
  d = {}
  for idx, col in enumerate(cursor.description):
      d[col[0]] = row[idx]
  return d
 
con = sqlite3.connect(":memory:")
con.row_factory = dict_factory
cur = con.cursor()
cur.execute("select 1 as a")
print cur.fetchone()["a"]
 
如果返回一個元組不能滿足需要,而你想要對列的基于名字的訪問,,那么你可以考慮將row_factory設置為高度優(yōu)化的sqlite3.Row類型,。Row既提供基于索引的,也提供基于名字的對列的訪問,,卻幾乎不需要消耗額外的內存,。它可能會比你自己定制的基于字典的訪問甚至基于db_row的解決方法還要好。
text_factory
使用這個屬性你可以控制對于TEXT數據類型返回什么樣的對象,。默認情況下,,這個屬性被設置為unicode,對于TEXT,,sqlite3模塊會返回Unicode對象,。如果你希望返回字節(jié)串(bytestrings)來替代,,你可以設置其為str。
你也可以將其設置為任何接受一個單一字節(jié)串參數并且返回最終對象的調用器,。
參考下面的解釋實例代碼:
 
import sqlite3
 
con = sqlite3.connect(":memory:")
cur = con.cursor()
 
#Create the table
con.execute("create table person(lastname, firstname):)
 
AUSTRIA = u"\xd6sterreich"
 
# by default, rows are returned as Unicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) == str
# the bytestrings will be encoded in UTF-8, unless you stored garbage in the
# database ...
assert row[0] == AUSTRIA.encode("uft-8")
 
# we can also implement a custom text_factory ...
# here we implement one that will ignore Unicode characters that cannot be
# decoded form UTF-8
con.text_factory = lambda x: unicode(x, "utf-8", "ignore")
cur.execute("select ?", ("this is latin1 and would normally create errors" + u"\xe4\xf6\xfc".encode("latin1"),))
row = cur.fetchone()
assert type(row[0]) == unicode
 
# pysqlite offers a builtin optimized text_factory that will return bytestring
# objects, if the data is in ASCII only, and otherwise return unicode objects
con.text_factory = sqlite3.OptimizedUnicode
cur.execute("select ?", (AUSTRIA,))
row = cur.fetchone()
assert type(row[0]) == unicode
 
cur.execute("select ?", ("germany",))
row = cur.fetchone()
assert type(row[0]) == str
 
total_changes
返回從數據庫連接開始后的所有被修改,,插入或刪除的行數。
13.13.3 游標對象(Cursor Objects)
一個游標實例擁有以下屬性和方法:
execute(sql, [parameters])
執(zhí)行一條SQL語句,。這條SQL語句可能是參數化了(parametrized)的(i. e. 用占位符替代了SQL文字),。sqlite3模塊支持兩種類型的占位符:問號(問好風格)和命名占位符(命名風格)。
這個例子展示了怎樣使用問號風格的參數:
 
import sqlite3
 
con = sqlite3.connect("mydb")
 
cur = con.cursor()
 
who = "Yeltsin"
age = 72
 
cur.execute("select name_last, age from people where name_last=? and age=?", (who, age))
print cur.fetchone()
 
下面的例子展示了如何使用命名風格:
 
import sqlite3
 
con = sqlite3.connect("mydb")
 
cur = con.cursor()
 
who = "Yeltsin"
age = 72
 
cur.execute("select name_last, age from people where name_last=:who and age=:age", {"who": who, "age": age})
print cur.fetchone()
 
execute()方法執(zhí)行一條單一SQL語句,。如果你試圖用其執(zhí)行多余一條的語句,,將會拋出一個警告(Warning)。你可以是用executescript()來再一次調用中執(zhí)行多條SQL語句,。
executemany(sql, seq_of_parameters)
執(zhí)行一條SQL語句利用所有參數序列,,或者從參數中得到的遍歷圖(mappings)。sqlite3模塊也允許使用迭代器生成參數來替代序列,。
 
import sqlite3
 
class IterChars:
  def __init__(self):
      self.count = ord('a')
 
  def __iter__(self):
      return self
 
  def next(self):
      if self.count > ord('z'):
          raise StopIteration
      self.count += 1
      return (chr(self.count - 1),) # this is a 1-tuple
 
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table characters(c)")
 
theIter = IterChars()
cur.executemany("insert into characters(c) values (?)", theIter)
 
cur.execute("select c from characters")
print cur.fetchall()
 
下面是一個使用生成器的小例子:
 
import sqlite3
 
def char_generator():
  import string
  for c in string.letters[:26]:
      yield (c,)
 
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.execute("create table charaters(c)")
 
cur.executemany("insert into characters(c) values (?)", char_generator())
 
cur.execute("select c from characters")
print cur.fetchall()
 
executescript(sql_script)
這是一個非標準的一次執(zhí)行多條SQL語句的簡便方法,。它首先提交一個COMMIT語句,然后將接收到的SQL語句作為參數,。
sql_script可以是一個字節(jié)串,,也可以是一個Unicode字符串。
Example:
 
import sqlite3
 
con = sqlite3.connect(":memory:")
cur = con.cursor()
cur.executescript("""
  create table person(
      firstname,
      lastname,
      age
  );
 
  create table book(
      title,
      author,
      published
  );
 
  insert into book(title, author, published)
  values (
      'Dirk Gently''s Holistic Detective Agency',
      'Douglas Adams',
      1987
  );
  """)
 
rowcount
雖然sqlite3模塊的游標類提供這一個屬性,,但是數據庫引擎本身對"rows affected"/"rows selected"的定義的支持要更快一些,。
對于select語句,rowcount總是None,,以為在所有行都被取出之前,,我們無從得知一個查詢所產生的行數。
對于delete語句,,如果你使用DELETE FROM而沒有任何條件的話,,SQLite將rowcount作為0報告。
根據Python DB API Spec的要求,,這個rowcount屬性“是-1,,如果在這個游標上還沒有executeXX()被執(zhí)行過,或者其最后一冊操作的rowcount對于接口不可知,?!?/div>
13.13.4 SQLite and Python types
 
13.13.4.1 Introduction
SQLite本身支持以下類型:NULL,INTEGER,REAL,TEXT,BLOB.
從而,如下的Python類型可以直接存入SQLite,,而不會出現任何問題:
Python type
 SQLite type
 
None
 NULL
 
int
 INTEGER
 
long
 INTEGER
 
float
 REAL
 
str(UTF8-encoded)
 TEXT
 
unicod
 TEXT
 
buffer
 BLOB
 
下面是默認情況下SQLite類型轉換為Python類型的對照:
SQLite type
 Python type
 
NULL
 None
 
INTEGER
 int或long,,取決于其大小
 
REAL
 float
 
BLOB
 buffer
 
sqlite3模塊的類型系統可以通過兩種方式擴展:可以通過對象適配器(object adaptation)將補充的Python類型存儲在一個SQLite數據庫中,也可以讓sqlite3模塊通過轉換器把SQLite類型轉換為不同的Python類型,。
13.13.4.2.2 使用適配器在SQLite數據庫中儲存補充的Python類型
如前所述,,SQLite本身只支持有限的幾種類型,。為了在SQLite中使用其他Python類型,你必須使它們適配sqlite3模塊支持的類型:None,int,long,float,str,unicode和buffer之一,。
sqlite3模塊使用Python對象適配器,,在PEP 246中對此有描述。使用的約定為PrepareProtocol,。
有兩種方法能夠使sqlite3模塊將定制的Python類型適配為被支持的類型,。
13.13.4.2.1 讓你的對象自適應
如果你自己編寫對象的話,這是一個很好的方法,。假設你有這樣的一個類:
class Point(object):
  def __init__(self, x, y):
      self.x, self.y = x, y
現在你希望將point儲存于SQLite中的一個單獨的列中,。首先你需要選擇一個支持的類型來替代point,。讓我們只是用一個字符串,,用分號分割兩個坐標。然后你需要為你的類添加一個__conform__(self, protocol)方法,,它必須返回轉換后的值,。參數protocol將會是PrepaerProtocol。
 
import sqlite3
 
class Point(object):
  def __init__(self, x, y):
      self.x, self.y = x, y
 
  def __conform__(self, protocol):
      if protocol is sqlite3.PrepareProrocol:
          return "%f;%f" % (self.x, self.y)
 
con = sqlite3.connect(":memory:")
cur = con.cursor()
 
p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print cur.fetchone()[0]
 
13.13.4.2.2 注冊一個適配器調用
另外一種可能是創(chuàng)建一個函數來將這種類型轉換為字符串替代,,并且使用register_adapter注冊這個函數,。
注意:進行適配的類型/類必須是一種新樣式(new-style)的類,也即,,它必須有對象作為其基類,。
 
import sqlite3
 
class Point(object):
  def __init__(self, x, y):
      self.x, self.y = x, y
 
def adapt_point(point):
  return "%f;%f" % (point.x, point.y)
 
sqlite3.register_adapter(Point, adapt_point)
 
con = sqlite3.connect(":memory:")
cur = con.cursor()
 
p = Point(4.0, -3.2)
cur.execute("select ?", (p,))
print cur.fetchone()[0]
 
對于Python的內置的datetime.date和datetime.datetime類型,sqlite3模塊有兩個默認的適配器?,F在我們假設要按照Unix的時間戳而不是ISO替代來存儲datetime.datetime對象,。
 
import sqlite3
import datetime, time
 
def adapt_datetime(ts):
  return time.mktime(ts.timetuple())
 
sqlite3.register_adapter(datetime.datetime, adapt_datetime)
 
con = sqlite3.connect(":memory:")
cur = cur.cursor()
 
now = datetime.datetime.now()
cur.execute("select ?", (now,))
print cur.fetchone()[0]
 
13.13.4.3 把SQLite值轉換為定制的Python類型
寫一個適配器可以讓你吧定制的Python類型存入到SQLite。但是要使它真正有用,,我們需要完成Python到SQLite再到Python的雙向工作,。
進入轉換器。
讓我們再次回到Point類,。我們使用分號分割的字符串在SQLite中儲存了x和y坐標,。
首先,我們會定義一個轉換函數,,接受這個字符串作為參數,,并且從這個字符串構建一個Point對象。
注意:轉換函數總是以字符串作為參數被調用,,而不管你以什么方式將數據存入SQLite,。
注意:轉換函數對大小寫敏感。
 
def convert_point(s):
  x, y = map(float, s.split(";"))
  return Point(x, y)
 
現在你需要讓sqlite3模塊知道,,你從數據庫中取出的實際上是一個point,。有兩種方法可以做到這一點:
<!--[if !supportLists]-->l         <!--[endif]-->通過聲明隱式進行
<!--[if !supportLists]-->l         <!--[endif]-->通過列名顯式進行
兩種方法都在“模塊常量(Module Constants)”中描述,,13.13.1章,在常量PARSE_DECLTYPES和PARSE_COLNAMES的記錄中,。
下面的例子說明了兩種方法:
 
import sqlite3
 
class Point(object):
  def __init__(self, x, y):
      self.x, self.y = x, y
  def __repr__(self):
      return "(%f;%f)" % (self.x, self.y)
 
def adapt_point(point):
  return "%f;%f" % (point.x, point.y)
 
def convert_point(s):
  x, y = map(float, s.split(";"))
  return Point(x, y)
 
# Register the adapter
sqlite3.register_adapter(Point, adapt_point)
 
# Register the converter
sqlite3.register_converter("point", convert_point)
 
p = Point(4.0, -3.2)
 
########################
# 1) Using declared types
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.cursor()
cur.execute("create table test(p point)")
 
cur.execute("insert into test(p) values (?)", (p,))
cur.execute("select p from test")
print "with declared types:", cur.fetchone()[0]
cur.close()
con.close()
 
#################
# 2) Using column names
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_COLNAMES)
cur = con.cursor()
cur.execute("create table test(p)")
 
cur.execute("insert into test(p) values (?)", (p,))
cur.execute('select p as "p [point]" from test')
print "with column names:", cur.fetchone()[0]
cur.close()
cur.close()
 
13.13.4.4 默認的適配器和轉換器
在datetime模塊中有對date和datetime類型有默認的適配器,。它們會被作為ISO日期或ISO時間戳送入SQLite中。
默認的轉換器以"date"名字對應datetime.date,,和"timestamp"名字對應datetime.datetime注冊,。
這樣,在大多數情況下,,你可以從Python中使用date/timestamps,,而不用做任何多余的工作。轉換器的格式也與SQLite的實驗性的date/time函數保持兼容,。
下面的例子演示了這一點:
 
import sqlite3
import datetime
 
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()
cur.execute("create table test(d date, ts timestamp)")
 
today = datetime.date.today()
now = datetime.datetime.now()
 
cur.execute("insert into test(d, ts) values (?, ?)", (today, now))
cur.execute("select d, ts from test")
row = cur.fetchone()
print today, "=>", row[0], type(row[0])
print now, "=>", row[1], type(row[1])
 
cur.execute('select current_date as "d [date]", current_timestamp as "ts [timestamp]"')
row = cur.fetchone()
print "current_date", row[0], type(row[0])
print "current_timestamp", row[1], type(row[1])
 
13.13.5 交易控制
默認情況下,,sqlite3模塊在一個數據變更語言(Data Modification Language-DML)(i.e. INSERT/UPDATE/DELETE/REPLACE)語句之前,隱式的打開交易,,并且在一個非DML,,非查詢(i.e. 任何非SELECT/INSERT/UPDATE/DELETE/REPLACE)語句之前,提交交易,。
所以,,如果你正處于一個交易之中,并且提交一個像CREATE TABLE ..., VACUUM, PRAGMA這樣的命令,,sqlite3模塊將在執(zhí)行這個名之前,,隱式的提交者個交易。有兩種原因要這樣做,。一是,,這些命令中的一部分不能在交易中工作。二是pysqlite需要對交易保持跟蹤(一個交易是否活躍),。
你可以控制pysqlite隱式的執(zhí)行那種"BEGIN"語句,,通過connect調用的isolation_level參數,或者通過連接的isolation_level屬性,。
如果你希望是自動執(zhí)行模式,,就把isolation_level設置為None。
否則,,就采用默認設置,,這將會產生普通的"BEGIN"語句,或者將其設置為SQLite支持的isolation級別:DEFERRED,IMMEDIATE或者EXCLUSIVE,。
因為sqlite3模塊需要對交易保持跟蹤,,所以你不能在你的SQL中使用OR ROLLBACK或者ON CONFLICT ROLLBACK。取而代之,你需要捕捉IntegrityError錯誤,,并且自己調用連接的rollback方法,。
13.13.6 高效的使用pysqlite
13.13.6.1 使用快捷方法
使用連接對象(Connection object)的非標準的execute,executemany和executescript方法,你可以書寫更簡潔的代碼,,因為你不用顯式的(通常是冗余的)創(chuàng)建游標對象,。這些快捷方法會隱式的創(chuàng)建并返回游標對象。這樣你就可以直接使用對連接對象的單一單一調用,,來執(zhí)行一個SELECT語句,,并對其進行迭代。
 
import sqlite3
 
persons = [
  ("Hugo", "Boss"),
  ("Calvin", "Klein")
  ]
 
con = sqlite3.connect(":memory:")
 
# Create ghe table
con.execute("create table person(firstname, lastname)")
 
# Fill the table
con.executemany("insert into person(firtname, lastname) values (?, ?)", persons)
 
# Print the table contents
for row in con execute("select firstname, lastname from person"):
  print row
 
# Using a dummy WHERE clause to not let SQLite take the shortcut table deletes.
print "I just deleted", con.execute("delete from person where 1=1").rowcount, "rows")
 
13.13.6.2 通過名字而不是索引來訪問列
sqlite3模塊的一個有用的特性是其內置的sqlite3.Row類,,它被設計用來作為一個行的代理,。
使用這個類包裝的行,既可以通過索引(有點像元組)來訪問,,也可以通過大小寫敏感的名字來訪問,。
 
import sqlite3
 
con = sqlite3.connect("mydb")
con.row_factory = sqlite3.Row
 
cur = con.cursor()
cur.execute("select name_last, age from people)
for row in cur:
  assert row[0] == row["name_last"]
  assert row["name_last"] == row["nAmE_1AsT"]
  assert row[1] == row["age"]
  assert row[1] == row["Age"]

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內容中的聯系方式,、誘導購買等信息,,謹防詐騙。如發(fā)現有害或侵權內容,,請點擊一鍵舉報,。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多