2015-04-06 124 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()