3

我有一个简单的 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
4

2 回答 2

3

如果您在 web2py 模型文件中运行该代码,那么无论如何您最终都会在每个 HTTP 请求上创建一个新连接。相反,您可能会考虑连接池

一个更简单的选择可能是使用 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])

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

请注意,我还没有尝试过这个,所以它可能需要一些调整,但是这些方面的东西应该可以工作。

如果您愿意,您甚至可以使用 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,而不实际执行选择。然后将 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)
于 2013-06-11T18:02:33.277 回答
0

我使用了 Anthony 的答案,现在具有如下所示的功能:

# 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 选项。

于 2013-06-12T07:52:18.570 回答