Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.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_Sqlalchemy_Asyncpg - Fatal编程技术网

Python 从sqlalchemy中定义的表获取创建查询字符串

Python 从sqlalchemy中定义的表获取创建查询字符串,python,sqlalchemy,asyncpg,Python,Sqlalchemy,Asyncpg,我有一个使用asyncpg连接数据库的异步python应用程序,我希望避免手动键入每个查询。我发现sqlalchemy core在这方面非常有用,但有一件事我很困惑。我希望我的应用程序能够在启动时创建数据库模式,而不是依赖已经创建的数据库模式,我还没有找到一种自动创建数据库模式的方法。我想要的是: import asyncio from sqlalchemy import Table, Column, Integer, String, MetaData import asyncpg meta

我有一个使用asyncpg连接数据库的异步python应用程序,我希望避免手动键入每个查询。我发现sqlalchemy core在这方面非常有用,但有一件事我很困惑。我希望我的应用程序能够在启动时创建数据库模式,而不是依赖已经创建的数据库模式,我还没有找到一种自动创建数据库模式的方法。我想要的是:

import asyncio

from sqlalchemy import Table, Column, Integer, String, MetaData
import asyncpg

metadata = MetaData()

people = Table(
    "people",
    metadata,
    Column("id", Integer, primary_key=True, autoincrement=True),
    Column("name", String)
)

class Database:
    def __init__(self, pool: asyncpg.pool.Pool):
        self.pool = pool

    async def ensure_schema(self):
        async with self.pool.acquire() as con:
            await con.execute(
                # this method doesn't really exist,
                # I'm just looking for something that would 
                # do the same - return following query:
                # CREATE TABLE IF NOT EXISTS people(id INTEGER PRIMARY KEY, name VARCHAR)
                people.get_create_query(checkfirst=True)
            )

async def main()
    pool = await asyncpg.create_pool(host="127.0.0.1", port=5432, user="postgres", password="postgres", database="test")
    db = Database(pool)
    await db.ensure_schema()

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
这里的问题是,sqlalchemy希望元数据绑定到引擎,但它不支持异步引擎。因此,我只想从声明的表中获取一个CREATE查询字符串,并将其传递给我的连接以执行

与此类似的可能是people.select,它不会立即执行,它只是创建一个对象,该对象还具有一个字符串表示,这就是要执行的查询


我可以将sql模式放在一个单独的文件中,并在启动时加载它,但它感觉不太好,因为每次更改模式时,我都需要在代码中的两个位置进行更改。有什么建议吗?

SQLAlchemy使用

self.Base.metadata.create_all(engine, tables=[people.__table__])

实现sqlalchemy可以打印出它在设置create_engineconnection-string、echo=True时执行的所有语句,并在创建新表时打印出来

CREATE TABLE people (
    id INTEGER NOT NULL,
    name VARCHAR,
    PRIMARY KEY (id)
)
我运行了调试器来找出这个字符串的来源,结果发现它可以这样获得

>>> from sqlalchemy.sql.ddl import CreateTable
>>> print(CreateTable(people))

我在文档中找不到这一点,所以我至少把它放在这里。

没错,但它对引擎有一些假设,而asyncpg.pool.pool.acquire不满足这些假设。这就是为什么我在寻找一些替代方法,只获取查询字符串,这样我就可以执行它。以下是官方文档: