为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

跃然一笑 2022-06-22 15:32:17
我在 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"我一生都无法弄清楚它有什么问题-有什么想法吗?
查看完整描述

2 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

这是最奇怪的事情。我已经从另一个工具中复制了我的查询文本,该工具用于在我的 pg DB 中导航到 VS Code 中。@EOhm 回答的最后一部分让我想到了在 VS Code 中输入整个内容而不是复制/粘贴。

一切正常。

即使粘贴的文本和我输入的内容在各个方面看起来都相同。所以显然有一些不可见的格式导致了这个问题。


查看完整回答
反对 回复 2022-06-22
?
三国纷争

TA贡献1804条经验 获得超7个赞

我不知道 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 TABLE

postgres=# create table schema.t1 (a varchar, b varchar, c varchar, f integer);

CREATE TABLE

postgres=# create table schema.t2 (x varchar, f integer);

CREATE TABLE

postgres=# create table schema.t3 (a varchar, b varchar, c varchar, d varchar);

CREATE TABLE

postgres=# commit;

使用以下脚本:


#!/usr/bin/python3

import 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')它应该是干净的。


查看完整回答
反对 回复 2022-06-22
  • 2 回答
  • 0 关注
  • 355 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号