3

I'm using MySQLdb to manipulate a MySQL database, and I have this following routine, to inject some data in a table called urls:

def insert_urls(dbconn, filenames):
    root = "<path>/"
    link = "http://<url>/"
    for f in filenames:
        filename = root + f + ".html"
        local_url = link + f + ".html"
        print(filename, local_url)
        sql = """
        INSERT INTO urls(url, filename) VALUES('%s', '%s');
        """ % (local_url, filename)
        print(sql)
        dbconn.execute_query(sql)

the declaration of the urls table is found here:

def create_urls_table():

    sql = """
        CREATE TABLE IF NOT EXISTS urls (
            id INT NOT NULL AUTO_INCREMENT,
            url BLOB NOT NULL,
            filename BLOB NOT NULL,
            PRIMARY KEY(id)
        ) ENGINE=INNODB;
    """
    return sql

dbconn is an object of the class Dbconn, defined as:

class Dbconn:
    def __init__(self,
                 host="",
                 user="",
                 pwd="",
                 database=""):

        self.host = host
        self.user = user
        self.pwd = pwd
        self.db = database
        self.cursor = None
        self.conn = None

        try:
            self.conn = MySQLdb.connect(host=self.host,
                                        user=self.user,
                                        passwd =self.pwd,
                                        db=self.db)
            self.cursor = self.conn.cursor()
            print "Connection established"
        except MySQLdb.Error, e:
            print "An error has occurred ", e

    def execute_query(self, sql=""):
        try:
            self.cursor.execute(sql)
        except MySQLdb.Error, e:
            print "An error has occurred ", e

After running the procedure insert_urls I get the following output:

  INSERT INTO urls(url, filename) VALUES ('http://<url>/amazon.html','<path>/amazon.html');
  INSERT INTO urls(url, filename) VALUES('http://<url>/linkedin.html', '<path>/linkedin.html');
  INSERT INTO urls(url, filename) VALUES('http://<url>/nytimes.html', '<path>/nytimes.html');

which I was able to inject manually into MySQL through the command line. However doing a SELECT * FROM urls query I found nothing. After I inserted two lines manually I got:

mysql> select * from urls;
+----+------------------------------------------------+------------------------+
| id | url                                            | filename               |
+----+------------------------------------------------+------------------------+
| 19 | http://<url>/yelp.html                         | <path>/yelp.html       |       
| 29 | http://<url>/amazon.html                       | <path>/amazon.html     |
+----+------------------------------------------------+------------------------+

Please note that the id value is being incremented ... which it may means data is being inserted, but not made persistent? Could someone please help me with that?

4

2 回答 2

4

您可能正在使用事务数据库,在这种情况下您必须调用

self.conn.commit()

(事实上​​,INNODB 是一个事务型数据库。)


您可以合并commitexecute_query

def execute_query(self, sql=""):
    try:
        self.cursor.execute(sql)
    except MySQLdb.Error as e:
        print "An error has occurred ", e
        self.conn.rollback()
    else:
        self.conn.commit()

但是,在某些情况下,您可能希望在调用commit或之前执行一些查询rollback。在这种情况下,您可能希望删除commitexecute_query在需要时显式调用,或者在退出-suite时commit使用上下文管理器进行调用。commitwith


请注意,MySQLdb连接是上下文管理器。你可以写

connection = MySQLdb.connect(
    host=config.HOST, user=config.USER,
    passwd=config.PASS, db=config.MYDB, )

with connection as cursor:
    cursor.execute(...)

并且连接将connection.commit()在退出时调用with-suite,或者connection.rollback()如果有异常。这是 MySQLdb.connections.py 中控制它的代码:

def __enter__(self): return self.cursor()

def __exit__(self, exc, value, tb):
    if exc:
        self.rollback()
    else:
        self.commit()
于 2013-08-27T23:39:11.143 回答
1

在您的execute()陈述之后,请致电commit()

self.cursor.execute(sql)
self.conn.commit()

有关详细信息,请参阅:python mysql 插入数据

于 2013-08-27T23:40:25.273 回答