寻找更加pythonic的方式来访问数据库

时间:2009-07-10 01:37:15

标签: python mysql

我有一堆遵循这种模式的python方法:

def delete_session(guid):
    conn = get_conn()
    cur = conn.cursor()

    cur.execute("delete from sessions where guid=%s", guid)

    conn.commit()
    conn.close()

是否有更多pythonic方式来执行原始sql。每种方法开头和结尾的两行开始让我烦恼。

我不是在寻找一个orm,我想坚持使用原始的sql。

6 个答案:

答案 0 :(得分:8)

您可以编写上下文管理器并使用with语句。例如,请参阅此博客文章:

http://jessenoller.com/2009/02/03/get-with-the-program-as-contextmanager-completely-different/

此外,python文档还有一个非常符合您需求的示例。请参阅本页8.1节,特别是开头的代码段:

db_connection = DatabaseConnection()
with db_connection as cursor:
    cursor.execute('insert into ...')
    cursor.execute('delete from ...')
    # ... more operations ...

答案 1 :(得分:3)

注意execute,第二个参数需要是[guid](只有一个项目的列表)。至于你的问题,我通常只使用一个类封装连接和游标,但看起来你可能更喜欢使用执行上下文对象,__enter__方法为你提供了一个光标{{ 1}}提交或回滚取决于终止是正常还是异常;这会使你的代码

__leave__

如果你喜欢这种风格,请告诉我们,我会告诉你如何写def delete_session(): with get_cursor() as cur: cur.execute(etc etc) 。其他人无疑会提出装饰师,所以你要写:

get_cursor

但我认为这使得提交/回滚等问题有点模糊。不过,如果这个是你的偏好,请再次告诉我们,我也可以告诉你如何写这个表格。

答案 2 :(得分:3)

“我有一堆遵循这种模式的python方法:”

这令人困惑。

要么你有很多函数,要么你有一堆类的方法。

一系列功能

改为做。

class SQLFunction( object ):
    def __init__( self, connection ):
        self.connection = connection
    def __call__( self, args=None ):
        self.cursor= self.connection.cursor()
        self.run( args )
        self.cursor.commit()
        self.cursor.close()

class DeleteSession( SQLFunction ):
    def run( self, args ):
        self.cursor.execute( "statement" )

delete_session = DeleteSession( connection )

你的函数声明长两行,但基本相同。 你可以func1( args ),因为它是一个可调用的对象。其余的 你的程序应保持不变。

一类方法

class SomeClass( object ):
    def __init__( self, connection ):
        self.connection= connection
    def sql_execute( self, statement, args= None )
        self.cursor= self.connection.cursor() 
        self.cursor.execute( statement, args if args is not None else [] )
        self.connection.commit()
        self.cursor.close()
    def delete_session( self ):
        self.sql_execute( "statement" )

您的所有方法都可以看起来像delete_session,并使用常见的sql_execute方法。

答案 3 :(得分:0)

它不一定是pythonic,只是更有条理:

def execSql(statement):
    conn = get_conn()
    cur = conn.cursor()
    cur.execute(statement)
    conn.commit()
    conn.close()

def delete_session(guid):
    execSql("delete from sessions where guid=%s"%(guid))

答案 4 :(得分:0)

装饰师?

class SqlExec:
   def __init__ (self, f):
      self.f = f
   def __call__ (self, *args):
      conn = get_conn() 
      cur = conn.cursor()
      cur.execute(self.f (*args))
      conn.commit()
      conn.close()

@SqlExec
def delete_session(guid):
      return "delete from sessions where guid=%s" % guid

答案 5 :(得分:0)

根据docs,如果你使用的是SQLite3,你根本不会需要一个Cursor,正如文档所说,它“通常是多余的”。

相反,您可以直接在连接对象上使用快捷方式execute executemanyexecutescript

import sqlite3

persons = [
    ("Hugo", "Boss"),
    ("Calvin", "Klein")
    ]

con = sqlite3.connect(":memory:")

# Create the table
con.execute("create table person(firstname, lastname)")

# Fill the table
con.executemany("insert into person(firstname, lastname) values (?, ?)", persons)

# Print the table contents
for row in con.execute("select firstname, lastname from person"):
    print row

print "I just deleted", con.execute("delete from person").rowcount, "rows"