猿问

在 Python 中执行原始 SQL 查询时出现问题:sqlalchemy.exc

我在 python 脚本中有一个查询,它在创建一些表后创建一个物化视图。


脚本是这样的:


    from sqlalchemy import create_engine, text


    sql = '''CREATE MATERIALIZED VIEW schema1.view1 AS 

            SELECT t1.a,

              t1.b,

              t1.c,

              t2.x AS d

            FROM schema1.t1 t1

            LEFT JOIN schema1.t2 t2 ON t1.f = t2.f

            UNION ALL

            SELECT t3.a, 

              t3.b, 

              t3.c, 

              t3.d

            FROM schema1.t3 t3;'''


    con=create_engine(db_conn)


    con.execute(sql)

当我直接在数据库上运行时,查询成功执行。


但是在python中运行脚本时,出现错误:


sqlalchemy.exc.ProgrammingError: (psycopg2.errors.SyntaxError) syntax error at or near "CREATE MATERIALIZED VIEW schema"

我一生都无法弄清楚它有什么问题-有什么想法吗?


跃然一笑
浏览 356回答 2
2回答

30秒到达战场

这是最奇怪的事情。我已经从另一个工具中复制了我的查询文本,该工具用于在我的 pg DB 中导航到 VS Code 中。@EOhm 回答的最后一部分让我想到了在 VS Code 中输入整个内容而不是复制/粘贴。一切正常。即使粘贴的文本和我输入的内容在各个方面看起来都相同。所以显然有一些不可见的格式导致了这个问题。

三国纷争

我不知道 SQLAlchemy 是否支持 MView-Creation,但它是否应该与特定的元数据函数(https://docs.sqlalchemy.org/en/13/core/schema.html)相似或完成。text 函数是为数据库独立的 DML 而设计的,而不是 DDL。也许它适用于 DDL(我不了解 SQLAlchemy),但根据设计,语法与您直接在数据库上执行时的语法不同,因为 SQLAlchemy 将从用户那里抽象出数据库的详细信息。如果 SQLAlchemy 没有为此提供一些方便的方法,并且您仍然有充分的理由使用 SQLAlchemy,您可以在数据库后端理解的方言中执行普通 SQL Statememt,因此只需省略textSQL 语句的 sqlalchemies 函数,例如:   from sqlalchemy import create_engine, text    sql = '''CREATE MATERIALIZED VIEW schema.view1 AS             SELECT t1.a,              t1.b,              t1.c              t2.x AS d            FROM schema.t1 t1            LEFT JOIN schema.t2 t2 ON t1.f = t2.f            UNION ALL            SELECT t3.a,               t3.b,               t3.c,               t3.d            FROM schema.t3 t3;'''    con=create_engine(db_conn)    con.raw_connection().cursor().execute(sql)(但当然,您必须注意后端类型,然后反对 SQLAlchemy 包装语句。)我直接使用 psycopg2 在我的 pg 服务器上进行了测试,没有任何问题。postgres=# create schema schema;CREATE TABLEpostgres=# create table schema.t1 (a varchar, b varchar, c varchar, f integer);CREATE TABLEpostgres=# create table schema.t2 (x varchar, f integer);CREATE TABLEpostgres=# create table schema.t3 (a varchar, b varchar, c varchar, d varchar);CREATE TABLEpostgres=# commit;使用以下脚本:#!/usr/bin/python3import psycopg2;conn = psycopg2.connect("dbname=postgres")cur = conn.cursor()cur.execute("""            CREATE MATERIALIZED VIEW schema.view1 AS            SELECT t1.a,              t1.b,              t1.c,              t2.x AS d            FROM schema.t1 t1            LEFT JOIN schema.t2 t2 ON t1.f = t2.f            UNION ALL            SELECT t3.a,              t3.b,              t3.c,              t3.d            FROM schema.t3 t3;""")conn.commit()cur.close()conn.close()我用最新版本的 python3.7/2.7 和当前版本的 psycopg2 模块和当前库(我有 11.5 pg 客户端和 2.8.3 psycopg2)从安装在最近的 linux 上的 pgdg 进行测试?你能像我一样尝试直接在 psycopg2 上执行吗?您是否还确保您的点是普通的 ascii 点,因为声明中的所有其他字符都在这种情况下?(还请记住,unicode 中可能存在不可见的代码点,这可能会导致此类问题。)如果您使用的是 Python,也许您可以将您的字符串转换为 ASCII 二进制文件,然后再转换回 Unicode-String。如果它没有引发错误,.encode('ASCII')它应该是干净的。
随时随地看视频慕课网APP

相关分类

Python
我要回答