psycopg2.pool.PoolError: trying to put unkeyed connection
时间: 2024-02-11 11:06:19 浏览: 23
这个错误通常是因为在使用 `psycopg2` 连接池时,连接对象没有设置 `key` 属性,导致连接池无法识别它。解决方法是在创建连接对象时,为其设置一个唯一的 `key` 属性,例如:
```python
import psycopg2.pool
# 创建连接池
conn_pool = psycopg2.pool.SimpleConnectionPool(
1, 10,
dbname='mydb', user='myuser', password='mypassword', host='localhost'
)
# 获取连接对象
conn = conn_pool.getconn()
# 设置连接对象的key属性
conn.key = 'unique_key'
# 使用连接对象进行数据库操作
# 将连接对象放回连接池
conn_pool.putconn(conn)
```
在获取到连接对象之后,通过设置 `key` 属性为一个唯一的值,就可以避免出现 `PoolError: trying to put unkeyed connection` 这个错误了。
相关问题
psycopg2.pool .ThreadedConnectionPool使用方法
`psycopg2.pool.ThreadedConnectionPool` 是 `psycopg2` 提供的另一个连接池类,与 `psycopg2.pool.SimpleConnectionPool` 不同的是,它可以在多线程环境下使用,并提供了自动回收超时连接的功能。以下是 `ThreadedConnectionPool` 的使用方法:
```python
import psycopg2
from psycopg2 import pool
# 创建连接池对象
pool = psycopg2.pool.ThreadedConnectionPool(
minconn=1, maxconn=10,
host='localhost', database='mydb', user='myuser', password='mypassword'
)
# 从连接池中获取连接
conn = pool.getconn()
# 使用连接对象执行数据库操作
cursor = conn.cursor()
cursor.execute('SELECT * FROM mytable')
# 将连接对象归还给连接池
pool.putconn(conn)
# 关闭连接池
pool.closeall()
```
在上面的示例中,我们创建了一个 `ThreadedConnectionPool` 对象,设置了最小连接数和最大连接数等参数。我们可以通过 `getconn()` 方法从连接池中获取一个连接对象,使用该连接对象执行数据库操作,然后通过 `putconn()` 方法将其归还给连接池。最后,我们可以通过 `closeall()` 方法关闭连接池。
需要注意的是,当使用 `ThreadedConnectionPool` 连接池时,获取连接和归还连接的操作都是线程安全的,因此可以在多线程环境中使用。此外,连接池会自动回收超时连接,以避免连接池中的连接被耗尽。可以通过 `ThreadedConnectionPool` 的构造函数参数指定连接超时时间。
psycopg2.pool 在多线程中如何使用
在多线程中使用 `psycopg2.pool`,需要创建一个连接池对象并将其传递给每个工作线程。在每个工作线程中,可以从连接池中获取一个连接对象,使用该连接对象执行数据库操作,然后将该连接对象归还给连接池。
以下是一个示例代码,展示如何在多线程中使用 `psycopg2.pool`:
```python
import psycopg2
from psycopg2 import pool
import threading
class DBPool:
def __init__(self, minconn, maxconn, **kwargs):
self._pool = psycopg2.pool.SimpleConnectionPool(minconn, maxconn, **kwargs)
def getConnection(self):
return self._pool.getconn()
def releaseConnection(self, conn):
self._pool.putconn(conn)
def worker(dbpool):
conn = dbpool.getConnection()
# 使用连接对象执行数据库操作
conn.cursor().execute('SELECT * FROM mytable')
dbpool.releaseConnection(conn)
dbpool = DBPool(1, 10, host='localhost', database='mydb', user='myuser', password='mypassword')
threads = []
for i in range(10):
t = threading.Thread(target=worker, args=(dbpool,))
threads.append(t)
t.start()
for t in threads:
t.join()
dbpool._pool.closeall()
```
在上面的示例中,我们首先定义了一个 `DBPool` 类,该类封装了 `psycopg2.pool.SimpleConnectionPool` 对象,并提供了获取连接和释放连接的方法。在 `worker` 函数中,我们从连接池中获取一个连接对象,使用该连接对象执行数据库操作,然后将其归还给连接池。最后,我们创建了10个工作线程,并将连接池对象传递给每个线程。每个线程都会从连接池中获取一个连接对象,使用该连接对象执行数据库操作,然后将其归还给连接池。
需要注意的是,当使用 `psycopg2.pool` 连接池时,需要在每个线程中获取连接对象,并在使用完毕后将其归还给连接池。如果不归还连接对象,那么连接池中的连接将会被耗尽,从而导致连接失败。