为什么Pandas和GeoPandas能够使用DBAPI(psycopg2)连接读取数据库表,但必须依靠SQLAlchemy来编写?

2024-04-20 04:41:04 发布

您现在位置:Python中文网/ 问答频道 /正文

上下文

我只是在试图从^{}脚本对某些数据库执行一些I/O操作时遇到了麻烦

当我想要connect到数据库时,我习惯使用^{}来处理connectionscursors

我的数据通常存储为^{}{a7}和/或^{}的等价物^{}

困难

为了从数据库表中读取数据

使用^{}:

我可以依赖它的^{}方法,它将con作为参数,如文档中所述:

con : SQLAlchemy connectable (engine/connection) or database str URI
        or DBAPI2 connection (fallback mode)'
        Using SQLAlchemy makes it possible to use any DB supported by that
        library. If a DBAPI2 object, only sqlite3 is supported. The user is responsible
        for engine disposal and connection closure for the SQLAlchemy connectable. See
        `here <https://docs.sqlalchemy.org/en/13/core/connections.html>`_

使用^{}:

我可以依赖它的^{}方法,它将con作为参数,如文档中所述:

con : DB connection object or SQLAlchemy engine
        Active connection to the database to query.

为了数据写入数据库表

使用^{}:

我可以依赖^{}方法,该方法将con作为参数,如文档中所述:

con : sqlalchemy.engine.Engine or sqlite3.Connection
        Using SQLAlchemy makes it possible to use any DB supported by that
        library. Legacy support is provided for sqlite3.Connection objects. The user
        is responsible for engine disposal and connection closure for the SQLAlchemy
        connectable See `here                 <https://docs.sqlalchemy.org/en/13/core/connections.html>`_

使用^{}:

我可以依赖于.to_sql()方法(直接依赖于Pandas{a15}),该方法将con作为参数,如文档中所述:

con : sqlalchemy.engine.Engine or sqlite3.Connection
        Using SQLAlchemy makes it possible to use any DB supported by that
        library. Legacy support is provided for sqlite3.Connection objects. The user
        is responsible for engine disposal and connection closure for the SQLAlchemy
        connectable See `here                 <https://docs.sqlalchemy.org/en/13/core/connections.html>`_

从这里,我很容易理解^{}是建立在^{}之上的,特别是它的^{}对象,很快,它就是一个可以处理地理数据的特殊^{}

但是我想知道为什么^{}有能力直接将^{}连接作为参数而不是^{}并且是否计划将后者作为参数

为什么在写入数据时,一方和另一方都不是这样呢?
我想(可能和其他许多人一样)直接给他们一个^{}{a4}参数,而不是依赖于^{}{a28}。
因为即使这个工具真的很棒,它也让我使用两个不同的框架连接到我的数据库,从而处理两个不同的连接字符串(我个人更喜欢^{}处理字典中的参数扩展的方式,以便正确地构建连接字符串,例如;psycopg2.connect(**dict_params)vsURL这里解释的注入,例如:Is it possible to pass a dictionary into create_engine function in SQLAlchemy?

变通办法

  1. 我首先用参数字典中的^{}创建连接字符串,方法如下:

    connParams = ("user={}", "password={}", "host={}", "port={}", "dbname={}")
    conn = ' '.join(connParams).format(*dict_params.values())
    
  2. 然后我发现这样做更好,更像是Python:

    conn = psycopg2.connect(**dict_params)
    
  3. 最后我用这个替换了它,这样我就可以互换地使用它来构建^{}{a4}或SQLAlchemy引擎:

    def connector():
        return psycopg2.connect(**dict_params)
    

    a)初始化a^{}connection现在由以下人员完成:

    conn = connector()
    curs = conn.cursor()
    

    b)并通过以下方式初始化^{}engine

    engine = create_engine('postgresql+psycopg2://', creator=connector)
    

(或与您的任何口味的db+driver)一起使用)

这在这里有很好的记录:
https://docs.sqlalchemy.org/en/13/core/engines.html#custom-dbapi-args
这里:
https://docs.sqlalchemy.org/en/13/core/engines.html#sqlalchemy.create_engine


[1]Dataframe to sql without Sql Alchemy engine
[2] How to write data frame to Postgres table without using SQLAlchemy engine?


Tags: orto方法https数据库docsfor参数
1条回答
网友
1楼 · 发布于 2024-04-20 04:41:04

可能to_sql需要SQLAlchemyConnectableEngineConnection)对象的主要原因是to_sql需要能够在数据库表不存在或需要替换时创建数据库表。pandas的早期版本专门使用DBAPI连接,但我怀疑,当他们向to_sql添加新功能时,他们发现自己编写了大量特定于数据库的代码来解决各种DDL实现的怪癖

当意识到他们在复制SQLAlchemy中已经存在的大量逻辑时,他们很可能决定通过简单地接受一个Engine/Connection对象并使用SQLAlchemy的(独立于数据库的)SQL表达式语言来创建表,从而将所有的复杂性“外包”给SQLAlchemy本身

it makes me use two different frameworks to connect to my database

不,因为.read_sql_query()还接受SQLAlchemy Connectable对象,所以您可以使用SQLAlchemy连接进行读写

相关问题 更多 >