Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何诊断金字塔中的额外SQLAlchemy连接_Python_Postgresql_Sqlalchemy_Connection Pooling_Pyramid - Fatal编程技术网

Python 如何诊断金字塔中的额外SQLAlchemy连接

Python 如何诊断金字塔中的额外SQLAlchemy连接,python,postgresql,sqlalchemy,connection-pooling,pyramid,Python,Postgresql,Sqlalchemy,Connection Pooling,Pyramid,当我的应用程序运行时,我经常会遇到关于连接池的问题(一个是“队列池大小限制为5溢出10已达到”,另一个是“致命:剩余的连接插槽保留给非复制超级用户连接”) 我有一种感觉,这是由于一些代码没有正确地关闭连接,或者其他代码贪婪地试图在不应该的时候打开新的连接,但是我使用默认的SQL Alchemy设置,所以我假设池连接默认值不应该是不合理的。我们正在使用作用域_会话(sessionmaker())方式创建会话,以便支持多线程 所以我的主要问题是,是否有一种工具或方法可以找出连接的方向?除了能够在新模

当我的应用程序运行时,我经常会遇到关于连接池的问题(一个是“队列池大小限制为5溢出10已达到”,另一个是“致命:剩余的连接插槽保留给非复制超级用户连接”)

我有一种感觉,这是由于一些代码没有正确地关闭连接,或者其他代码贪婪地试图在不应该的时候打开新的连接,但是我使用默认的SQL Alchemy设置,所以我假设池连接默认值不应该是不合理的。我们正在使用作用域_会话(sessionmaker())方式创建会话,以便支持多线程

所以我的主要问题是,是否有一种工具或方法可以找出连接的方向?除了能够在新模式创建(不应该创建)后立即看到外,是否有任何明显的反模式可能导致这种效果

金字塔是非常不固执己见的,对于DB连接,似乎有两种主要方法(金字塔似乎同样支持)。在我们的例子中,我开始工作时的代码库使用了一种方法(我称之为“globals”方法),我们已经同意切换到另一种方法,这种方法较少依赖globals,更多地依赖Pythonic习语

关于我们的体系结构:该应用程序包含一个包含金字塔项目的repo,然后来自许多其他git模块,每个模块都有自己的连接设置。“全局”方式以非常非ORM的方式连接到数据库,例如:

(in each repo's __init__ file)
def load_database:
    global tables

    tables['table_name'] = Table(
        'table_name', metadata,
        Column('column_name', String),
    )
代码中经常出现一些相关的全局变量:

def function_needing_data(field_value):
    global db, tables
    select = sqlalchemy.sql.select(
        [tables['table_name'].c.data], tables['table_name'].c.name == field_value)
    return db.execute(select)
这个tables变量锁存在每个gitrepo中,它添加了更多的表定义,全局表以某种方式管理工作,提供对所有表的访问

我们采用的方法(尽管目前代码中仍有这两种方法的一部分)是通过集中连接,将所有元数据绑定到其中,然后以ORM方法查询数据库:

(model)
class ModelName(MetaDataBase):
    __tablename__ = "models_table_name"
    ... (field values)

(function requiring data)
from models.db import DBSession
from models.model_name import ModelName

def function_needing_data(field_value):
    return DBSession.query(ModelName).filter(
        ModelName.field_value == field_value).all()

我们基本上已经将代码转移到了后一种方法,这感觉是正确的,但也许我的意图是错误的。我不知道这两种方法是否都有本质上的优点或缺点,但这(其中一种方法)是否可能是问题的一部分,因此我们会一直失去连接?是否有我应该注意的迹象?

当您使用(Pyramid_tm)时,Pyramid功能最好(在处理连接池方面)。这为金字塔应用程序通常如何设置数据库连接以及应该如何设置数据库连接提供了一些有用的见解

在我的例子中,有必要包括pyramid_tm包,然后删除一些手动提交会话更改的实例,因为pyramid_tm将在没有理由不提交更改时自动提交更改

[更新]

我仍然有连接池问题,尽管这些问题要少得多。经过大量调试后,我发现金字塔事务管理器(如果您正确使用的话)根本不应该是问题所在。我遇到的其他连接池问题与通过cron作业运行的脚本有关。脚本完成后将释放其连接,但错误的代码设计可能会导致在前一个脚本运行时打开同一个脚本并开始运行的情况(导致它们都运行得较慢,足够慢到在脚本的第三个实例启动时运行这两个脚本,以此类推)

这是一个与语言和数据库无关的错误,因为它源于糟糕的作业脚本设计,但值得记住。在我的例子中,脚本末尾有一个“&”,因此每个实例都作为后台进程启动,等待10秒,然后生成另一个实例,而不是确保第一个作业启动并完成,然后等待10秒,然后启动另一个

希望这有助于调试这个非常令人沮丧和棘手的问题