2015-04-06 49 views
0

我有一個簡單的Python數據庫應用程序與SQLite。我寫了一個簡單的程序來創建數據庫並插入一些值。但是,數據庫已創建,但未插入新值,但我不知道爲什麼:插入SQLite文件Python - 不起作用

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import sqlite3 as lite 
import sys 


def CreateTable(): 
    try: 

     connection = lite.connect(':memory:') 

     with connection: 

      cursor = connection.cursor() 
      sql = 'CREATE TABLE IF NOT EXISTS Authors' + '(ID INT PRIMARY KEY NOT NULL, FIRSTNAME TEXT, LASTNAME TEXT, EMAIL TEXT)' 
      cursor.execute(sql) 

      data = '\n'.join(connection.iterdump()) 
      with open('authors.sql', 'w') as f: 
       f.write(data) 

    except lite.Error, e: 
     if connection: 
      connection.rollback() 
    finally: 
     if connection: 
      cursor.close() 
      connection.close() 

def Insert(firstname, lastname, email) : 
    try: 

     connection = lite.connect('authors.sql') 

     with connection: 

      cursor = connection.cursor() 
      sql = "INSERT INTO Authors VALUES (NULL, %s, %s, %s)" % (firstname, lastname, email) 
      cursor.execute(sql) 

      data = '\n'.join(connection.iterdump()) 
      with open('authors.sql', 'w') as f: 
       f.write(data) 

    except lite.Error, e: 
     if connection: 
      connection.rollback() 
    finally: 
     if connection: 
      cursor.close() 
      connection.close() 



CreateTable() 
Insert('Tibby', 'Molko', '[email protected]') 
+0

爲什麼你有兩個不同的數據庫連接?一個是內存中,另一個是文件。 – 2015-04-06 11:24:17

+0

,因爲我需要在已創建的數據庫中附加一些值。那可能嗎? – yak 2015-04-06 11:24:46

+0

然後只需打開一個連接到*那個數據庫*。 SQLite數據庫文件不像文本文件,你不會追加到它們。將它留給SQLite來管理文件中的數據。 – 2015-04-06 11:25:14

回答

1

您誤解了connection.iterdump()。您正在創建SQL文本,指示SQLite稍後再次執行。它不是數據庫本身。如果您只想輸出SQL語句,您可以直接編寫SQL語句,那麼首先將它傳遞給SQLite是沒有意義的。

你也不能用SQL語句'連接'SQLite到文本文件;您必須將這些語句作爲文本加載並重新播放。然而這不是我認爲你想要的。

您可以連接到現有數據庫以插入其他行。你想有添加數據每一次,只需連接

def CreateTable(): 
    connection = lite.connect('authors.db') 

    try: 
     with connection as: 
      cursor = connection.cursor() 
      sql = '''\ 
       CREATE TABLE IF NOT EXISTS Authors (
        ID INT PRIMARY KEY NOT NULL, 
        FIRSTNAME TEXT, 
        LASTNAME TEXT, 
        EMAIL TEXT) 
      ''' 
      cursor.execute(sql) 

    finally: 
     connection.close() 


def Insert(firstname, lastname, email) : 
    connection = lite.connect('authors.db') 

    try: 
     with connection: 
      cursor = connection.cursor() 
      sql = "INSERT INTO Authors VALUES (NULL, ?, ?, ?)" 
      cursor.execute(sql, (firstname, lastname, email)) 

    finally: 
     connection.close() 

注意,使用的連接作爲一個上下文管理器已經保證了交易被提交或回滾,這取決於有是一個例外。

總體而言,您希望在此處瞭解異常情況;如果你不能連接到你想知道的數據庫。我簡化了連接處理。關閉連接會自動關閉所有剩餘的遊標。

最後但至少,我將您的插入切換爲使用SQL參數。切勿使用字符串插值來代替參數。使用參數可以使數據庫緩存語句分析結果,並且大部分都可以防止SQL注入攻擊。

+0

謝謝,現在我明白了。我唯一可以添加到你的答案是,你需要寫'ID INTEGER PRIMARY KEY NOT NULL'而不是'ID INT PRIMARY KEY NOT NULL'才能夠寫入'INSERT INTO作者VALUES(NULL,?,?, ?)' – yak 2015-04-09 19:13:29

1

您無法使用sql命令連接到文本文件。 sqlite3.connect預計或創建一個二進制文件。

+0

OP在哪裏使用文本文件插入? – 2015-04-06 11:23:52

+0

所以我怎樣才能追加一些值到現有的sqlite數據庫? – yak 2015-04-06 11:24:17

+0

啊,我明白你的意思了,內存數據庫處理起來很怪異。 – 2015-04-06 11:24:46

1

您不會在您的連接上調用提交。您也不應該自己寫入數據庫文件,數據庫引擎正在寫入該文件。

試着通過前幾個例子sqlite documentation,應該很清楚即可。

1

你didd commit它。對於writing進入數據庫,它應該被提交。對於讀取(選擇)操作,不需要。

try: 
    with connection: 
     cursor = connection.cursor() 
     sql = "INSERT INTO Authors VALUES (NULL, ?, ?, ?)" 
     cursor.execute(sql, (firstname, lastname, email)) 
     connection.commit() # or cursor.commit() 


finally: 
    connection.close()