在Python中使用psycopg2执行.sql模式

47

我有一个存储在.sql文件中的PostgreSQL模式。它看起来像这样:

CREATE TABLE IF NOT EXISTS users (
    id INTEGER PRIMARY KEY,
    facebook_id TEXT NOT NULL,
    name TEXT NOT NULL,
    access_token TEXT,
    created INTEGER NOT NULL
);

连接到数据库后,我该如何运行这个架构?

我的现有Python代码适用于SQLite数据库:

# Create database connection
self.connection = sqlite3.connect("example.db")

# Run database schema
with self.connection as cursor:
    cursor.executescript(open("schema.sql", "r").read())

但是psycopg2游标没有executescript方法,那么我该怎么做呢?

2个回答

85

你可以直接使用 execute

with self.connection as cursor:
    cursor.execute(open("schema.sql", "r").read())

尽管您可能想首先将psycopg2设置为 autocommit 模式,以便您可以使用脚本自己的事务管理。

如果psycopg2提供了一种更智能的模式,在该模式下它按语句读取文件并将其发送到数据库,那就太好了,但就我所知,目前没有这样的模式。当面临$$引用(及其$delimiter$变体,其中分隔符可以是任何标识符)、standard_conforming_stringsE''字符串、嵌套函数体等情况时,它需要一个相当可靠的解析器才能正确执行。

请注意,这不会与以下内容配合使用:包含psql反斜杠命令的任何内容

  • COPY .. FROM STDIN
  • 非常长的输入
  • ...因此也不适用于pg_dump产生的转储。


    1
    Craig,当向psql提供多语句字符串时,它会做什么?它是否有自己的解析器来检测分号是否是语句分隔符还是字符串/注释的一部分? - piro
    1
    @Matt3o12 【这不是内存泄漏;我认为你需要查找一下它的实际含义】(http://en.wikipedia.org/wiki/Memory_leak)。它可能会使用大量RAM并耗尽可用内存。这只是一个玩具示例,当然你不会用一个庞大的脚本来执行这么简单的操作。你会使用 psql,自己解析和拆分输入,并将其馈送到 psycopg2 中。 - Craig Ringer
    1
    @Matt3o12 据我所知,这种代码没有特定的名称。我只会说:“对于大输入,该代码可能会耗尽RAM,因为它将整个输入加载到RAM中,而不是流式传输或逐步处理它。” 内存泄漏 是一个非常具体的术语,人们经常滥用这个术语,所以有点令人沮丧;-) - Craig Ringer
    当我在某种类型的脚本上执行时,这对我不起作用。我有一个带有“COPY ... FROM stdin;”语句的脚本,然后是复制转储。在psql中可以工作,但在这种方法中不行。 - sudo
    1
    @sudo COPY需要特殊处理,不能仅作为普通查询发送。psycopg2支持复制操作,但您必须单独提取复制查询和数据并进行处理。 - Craig Ringer
    显示剩余8条评论

    11

    由于声望不足,我无法回复选定答案的评论,所以我将提供一个答案来帮助解决复制(COPY)问题。

    根据您数据库的大小,pg_dump --inserts 输出INSERT而不是COPY


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接