web2py webserver - 保持与外部SQL服务器连接的最佳方法?

时间:2013-06-11 08:33:55

标签: python postgresql python-2.7 database-connection web2py

我有一个简单的web2py服务器,用于可视化PostgreSQL服务器中的数据。以下函数都是web2py中全局模型的一部分。

当前获取数据的解决方案非常简单。每次我连接,并在获得数据后,我关闭连接:

# Old way:
# (imports excluded)  
def get_data(query):
    postgres_connection = psycopg2.connect("credentials")
    df = psql.frame_query(query, con=postgres_connection) # Pandas function to put data from query into DataFrame
    postgres.close()
    return df

对于小型查询,打开和关闭连接需要大约9/10的时间来运行该功能。

这是一个很好的方法吗?如果没有,有什么更好的方法?

# Better way?
def connect():
    """
    Create a connection to server.
    """
    return psycopg2.connect("credentials")

db_connection = connect()

def create_pandas_frame(query):
    """
    Get query if connection is open.
    """
    return psql.frame_query(query, con=db_connection)    

def get_data(query):
    """
    Try to get data, open a new conneciton if connection is closed.
    """
    try:
        data = create_pandas_frame(query)
    except:
        global db_connection
        db_connection = connect()
        data = create_pandas_frame(query)
    return data

2 个答案:

答案 0 :(得分:2)

如果您在web2py模型文件中运行该代码,您最终还是会在每个HTTP请求上创建一个新连接。相反,您可以考虑connection pooling

更简单的选择可能是使用web2py DAL来获取数据。类似的东西:

from pandas.core.api import DataFrame
db = DAL([db connection string], pool_size=10, migrate_enabled=False)
rows = db.executesql(query)
data = DataFrame.from_records(rows, columns=[list, of, column, names])

如果为DAL()指定pool_size参数,它将自动维护一个连接池,以便跨请求使用。

注意,我没有试过这个,所以可能需要一些调整,但这些内容应该有效。

如果您愿意,您甚至可以通过定义数据库表模型使用DAL生成SQL:

db.define_table('mytable',
    Field('field1', 'integer'),
    Field('field2', 'double'),
    Field('field3', 'boolean'))

rows = db.executesql(db(db.mytable.id > 0)._select())
data = DataFrame.from_records(rows, columns=db.mytable.fields)

._select()方法只生成SQL而不实际执行select。然后将SQL传递给.executesql()以获取数据。

另一种方法是创建一个特殊的Pandas处理器,并将其作为processor参数传递给.select()

def pandas_processor(rows, fields, columns, cacheable):
    return DataFrame.from_records(rows, columns=columns)

data = db(db.mytable.id > 0).select(processor=pandas_processor)

答案 1 :(得分:0)

我使用了安东尼的答案,现在的功能看起来像这样:

# In one of the models files.
from pandas.core.api import DataFrame
external_db = DAL('postgres://connection_stuff',pool_size=10,migrate_enabled=False)
def create_simple_html_table(query):
    dict_from_db = external_db.executesql(query, as_dict=True)
    return DataFrame(dict_from_db).to_html()

然后在视图或控制器中使用以下命令创建html表:

# In Controller:
my_table = create_simple_html_table('select * from random_table limit 50')
# In View:
{{=XML(create_simple_html_table('select * from random_table limit 50'))}}

我仍然需要做更多测试,但到目前为止我的理解是这个解决方案让我从外部数据库查询内容并让web2py保持连接,让web2py为所有用户使用相同的连接。

请注意,只有您想要做的就是使用原始SQL读取和写入Postgres服务器时,此解决方案才有用。

如果你想使用DAL进行读写,你需要尝试找到名为MyDAL的DAL替代品,或者在Postgres中使用search_path选项。