python MySQLdb 一个连接connection多个cursor

使用MySQLdb时,如果创建一个连接connection,多个线程同时使用,会不会有问题?

在下文中,我们将模拟这种场景,看是否会出现问题。

1.示例

1.1 正常的情况

创建一个连接,两个线程同时使用这个连接,生成游标cursor,进行查询,并输出结果。

程序启动后,让线程1睡眠1s,保证让线程2线执行。

import MySQLdb
import threading
import time


def get_connection():
        host = "127.0.0.1"
        port = 3306
        user = "root"
        passwd = "Aa123456"

        conn = MySQLdb.connect(host=host, port=port, user=user,passwd=passwd, connect_timeout=2, charset="utf8")
        return conn


def thread1_runtime(conn, sql):
        time.sleep(1)
        cursor = conn.cursor()
        cursor.execute(sql)

        ret = cursor.fetchone()
        thread_name = threading.current_thread().name
        print("thread name:%s, ret:%s" %(thread_name, ret))

def thread2_runtime(conn, sql):
        cursor = conn.cursor()
        cursor.execute(sql)

        ret = cursor.fetchone()
        thread_name = threading.current_thread().name
        print("thread name:%s, ret:%s" %(thread_name, ret))
        
        
if __name__ == "__main__":

        thread1_sql = "select 1"
        thread2_sql = "select 2"

        conn = get_connection()

        thread1 = threading.Thread(target=thread1_runtime, name="thread 001", args=(conn, thread1_sql))
        thread2 = threading.Thread(target=thread2_runtime, name="thread 002", args=(conn, thread2_sql))


        thread1.start()
        thread2.start()


        thread1.join()
        thread2.join()

        print("...main exit....")

从结果可以看到,一切正常。

output:

thread name:thread 002, ret:(2,)

thread name:thread 001, ret:(1,)

…main exit…

1.2 异常的情况

以下例子中,程序启动后,线程1和线程2使用同一连接创建新的游标cursor,执行查询。

接着,线程1睡眠1秒,线程2睡眠2秒。
最后各自打印查询结果。

import MySQLdb
import threading
import time


def get_connection():
        host = "127.0.0.1"
        port = 3306
        user = "root"
        passwd = "Aa123456"

        conn = MySQLdb.connect(host=host, port=port, user=user,passwd=passwd, connect_timeout=2, charset="utf8")
        return conn


def thread1_runtime(conn, sql):
        cursor = conn.cursor()
        cursor.execute(sql)

        time.sleep(1)
        ret = cursor.fetchone()
        thread_name = threading.current_thread().name
        print("thread name:%s, ret:%s" %(thread_name, ret))

def thread2_runtime(conn, sql):
        cursor = conn.cursor()
        cursor.execute(sql)

        time.sleep(2)
        ret = cursor.fetchone()
        thread_name = threading.current_thread().name
        print("thread name:%s, ret:%s" %(thread_name, ret))

if __name__ == "__main__":

        thread1_sql = "select 1"
        thread2_sql = "select 2"

        conn = get_connection()

        thread1 = threading.Thread(target=thread1_runtime, name="thread 001", args=(conn, thread1_sql))
        thread2 = threading.Thread(target=thread2_runtime, name="thread 002", args=(conn, thread2_sql))

        thread1.start()
        thread2.start()

        thread1.join()
        thread2.join()

        print("...main exit....")

output:

Exception in thread thread 002:
Traceback (most recent call last):
File “/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py”, line 916, in _bootstrap_inner
self.run()
File “/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/threading.py”, line 864, in run
self._target(*self._args, **self._kwargs)
File “one_conn_mutiple_cursor.py”, line 28, in thread2_runtime
cursor.execute(sql)
File “/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/cursors.py”, line 198, in execute
res = self._query(query)
File “/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/cursors.py”, line 304, in _query
db.query(q)
File “/Users/lanyang/workspace/orange-service/.venv/lib/python3.6/site-packages/MySQLdb/connections.py”, line 217, in query
_mysql.connection.query(self, query)
MySQLdb._exceptions.ProgrammingError: (2014, “Commands out of sync; you can’t run this command now”)

thread name:thread 001, ret:(1,)
…main exit…

从打印结果可以看到,线程1可以正常打印结果,但线程2报错了。

线程1睡眠先结束,去获取查询结果,可以打印。
线程2睡眠后结束,再去获取查询结果,已经无法获取结果了。

2.总结

从上面例子中,我们可以得出结论:

一个连接connection同一个时间点只能有一个cursor,执行sql,并获取结果。

所以,不要在多个线程中同时使用一个连接connection,否则会出现不可预料的结果。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 使用Python连接数据库并创建一个新表格的步骤如下: 1. 首先,需要安装Python中的数据库驱动程序,例如pymysql、psycopg2等。这里以pymysql为例,可以使用以下命令安装: ``` pip install pymysql ``` 2. 接下来,需要在Python中导入pymysql模块,并使用pymysql.connect()函数连接到数据库。例如,连接到本地MySQL数据库的示例代码如下: ```python import pymysql # 连接到本地MySQL数据库 conn = pymysql.connect( host='localhost', user='username', password='password', db='database_name' ) ``` 在上面的代码中,需要将“username”和“password”替换为实际的数据库用户名和密码,“database_name”替换为实际的数据库名称。 3. 连接成功后,可以使用cursor()方法获取游标对象,并使用execute()方法执行SQL语句。例如,创建一个名为“users”的新表格的示例代码如下: ```python # 获取游标对象 cursor = conn.cursor() # 创建新表格 sql = ''' CREATE TABLE users ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, PRIMARY KEY (id) ) ''' cursor.execute(sql) # 提交更改 conn.commit() ``` 在上面的代码中,首先获取游标对象,然后使用SQL语句创建一个名为“users”的新表格。最后,使用commit()方法提交更改。 4. 创建完成后,需要关闭游标对象和数据库连接。例如,完整的示例代码如下: ```python import pymysql # 连接到本地MySQL数据库 conn = pymysql.connect( host='localhost', user='username', password='password', db='database_name' ) # 获取游标对象 cursor = conn.cursor() # 创建新表格 sql = ''' CREATE TABLE users ( id INT(11) NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL, PRIMARY KEY (id) ) ''' cursor.execute(sql) # 提交更改 conn.commit() # 关闭游标对象和数据库连接 cursor.close() conn.close() ``` 在上面的代码中,使用了close()方法关闭了游标对象和数据库连接。 ### 回答2: 使用Python连接数据库并创建一个新表格的步骤如下: 首先,我们需要安装和导入Python的数据库驱动程序,如MySQLdbpymysql等。假设我们使用MySQL数据库进行演示。 其次,在Python程序中,我们需要引入相应的库,并与数据库建立连接。使用数据库驱动程序提供的connect()函数来建立连接,并提供必要的主机名、用户名、密码、数据库名等参数。 接着,我们可以使用数据库连接对象的cursor()方法创建一个游标对象。游标对象用来执行SQL语句以及获取结果。 然后,我们可以使用游标对象的execute()方法执行SQL语句来创建新的表格。SQL语句可以是CREATE TABLE语句,用于定义新表格的结构,包括表格名、字段名、数据类型等。 最后,通过commit()方法提交执行的SQL语句,并通过close()方法关闭数据库连接。 下面是一个简单的示例代码: ```python import pymysql # 建立数据库连接 db = pymysql.connect(host='localhost', user='root', password='password', database='test') # 创建游标对象 cursor = db.cursor() # 创建新表格 sql = "CREATE TABLE my_table (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), age INT)" cursor.execute(sql) # 提交执行的SQL语句 db.commit() # 关闭数据库连接 db.close() ``` 以上代码示例使用pymysql连接MySQL数据库,并创建了一个名为my_table的新表格,该表格包含id、name和age三个字段。 希望这个回答能够帮助你! ### 回答3: 使用Python可以很方便地连接数据库并创建新表格。首先,我们需要安装一个Python的数据库驱动程序,如MySQL Connector,pymysql等。 在安装好相应的驱动程序之后,我们需要导入驱动程序,并建立与数据库的连接。这可以通过使用驱动程序提供的`connect()`函数来实现,我们需要传入相关数据库的连接信息,如数据库的地址、用户名、密码等。 接下来,在建立好与数据库的连接后,我们可以使用连接对象的`cursor()`方法创建一个游标对象,通过游标对象来执行SQL语句。 例如,我们想要在名为"mydatabase"的数据库中创建一个名为"mytable"的新表格,可以执行如下的Python代码: ```python import mysql.connector # 建立与数据库的连接 connection = mysql.connector.connect( host="localhost", user="root", password="password", database="mydatabase" ) # 创建一个游标对象 cursor = connection.cursor() # 创建新表格的SQL语句 create_table_query = "CREATE TABLE mytable (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), age INT)" # 执行SQL语句 cursor.execute(create_table_query) # 提交更改到数据库 connection.commit() # 关闭游标连接 cursor.close() connection.close() ``` 在上述代码中,我们首先建立了与数据库的连接,然后创建了一个游标对象。接着,我们定义了一个CREATE TABLE语句,用于创建新表格。然后,通过游标对象的`execute()`方法执行SQL语句。最后,我们通过连接对象的`commit()`方法提交更改,关闭游标连接。 使用以上代码,我们可以成功地在数据库中创建了一个名为"mytable"的新表格。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值