2013-03-16 17 views
1

我需要一种方法来访问我的python3应用程序在内存中(':memory:')在命令行界面工具sqlite3中创建的数据库。这个想法是为用户提供标准sqlite3工具的便利,而不是在python本身中重新实现sqlite shell。在python和sqlite3之间传输数据库cli工具

同样,我们的目标是:

数据库中存储在我的python程序打开 - >编辑/处理在sqlite3的CLI工具数据库 - >移动的(可能)修改的数据库回我Python程序。

我试着向:

def sqlite_cli(self): 
    # Spawn the original sqlite3 cli interface 
    # Dump the database in a named temporary file. Read it back into 
    # memory. At close() the tempfile will be erased. 
    with tempfile.NamedTemporaryFile(delete=True) as tf: 
     for line in self.connection.iterdump(): 
      tf.write(bytes(line, 'ascii')) 

     # Work with the database through sqlite3 
     subprocess.call(['sqlite3', '-init', tf.name]) 

     # Read the potentially modified database 
     # !!!!!!!!!!!!!!!! 
     # Here happens the logic gap: The sqlite3 tool doesn't 
     # save modifications to the file opend as the -init argument. 
     # How can I save the modifications done within sqlite3 as a 
     # sql text file ready to be read back into the app?! 
     tf.seek(0) 
     edited_db = tf.read() 

     # Delete all tables residing in memory 
     try: 
      for t in ACCMAN_TABLES: 
       self.cursor.execute('DROP TABLE IF EXISTS %s' % t) 
      self.connection.commit() 
      # Add the (maybe) edited one 
      self.cursor.executescript(edited_db.decode(encoding='utf-8')) 
      self.connection.commit() 
     except sqlite3.Error as e: 
      logger.error("sqlite_cli(): %s" % e.args[0]) 

     tf.close() 

在这种情况下,我需要一种方法来保存源码-init名无论是在SQL或二进制打开的数据库上进行的所有修改(在正常的...)格式。

编辑:一个解决办法是让用户对数据库做他的东西,然后他结束会话(.Q .quit .exit捕捉标准输入)之前,我可以把一个中介

.output outfile.sql 
.dump 
.quit 

在文件系统上重定向整个数据库(以及它的修改!),然后将创建的文件读回python应用程序。但是,这是如此丑陋和不雅...

+4

为什么要将数据库保存在内存中?首先在临时文件中打开它,并且让Python和'sqlite3'交替使用同一个文件是不是更容易? – millimoose 2013-03-16 12:55:58

+0

因为在脚本本身旁边不应该有任何文件。应用程序的目的是从脚本文件本身提取数据库(aes encrypted和base64编码)并将其读入内存。数据库中的信息非常敏感,不应该保存在文件系统中。 – 2013-03-21 09:11:51

+0

在这种情况下,将数据库转储到SQL文件中的建议令人困惑。在第一个建议的解决方案中使用'NamedTemporaryFile'也一样。两者具有完全相同的安全含义。 – millimoose 2013-03-21 10:03:54

回答

0

我不认为你会喜欢这个答案,但我会考虑在你的应用程序中编写“模型”作为能够接收XML的“服务器” -rpc电话。这样,您的“控制器”(以及外部控制器)就可以访问数据库并执行您允许他们执行的任何操作。将类的方法作为XML-RPC服务器公开很容易。请参阅http://docs.python.org/2/library/xmlrpclib.html?highlight=xmlrpc#xmlrpclib