有没有一种"Pythonic"方法(我的意思是,没有"纯SQL"查询)可以用SQLAlchemy定义SQL视图?

推荐答案

Update:另请参见SQLAlchemy用法配方here

据我所知,创建(只读非materialized )视图是不支持开箱即用的.但是在SQLAlchemy 0.7中添加这个功能很简单(类似于我给出的here个示例).你只需要写一个compiler extension CreateView.有了这个扩展,您就可以写了(假设t是一个包含id列的表对象)

createview = CreateView('viewname', t.select().where(t.c.id>5))
engine.execute(createview)

v = Table('viewname', metadata, autoload=True)
for r in engine.execute(v.select()):
    print r

以下是一个有效的例子:

from sqlalchemy import Table
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Executable, ClauseElement

class CreateView(Executable, ClauseElement):
    def __init__(self, name, select):
        self.name = name
        self.select = select

@compiles(CreateView)
def visit_create_view(element, compiler, **kw):
    return "CREATE VIEW %s AS %s" % (
         element.name,
         compiler.process(element.select, literal_binds=True)
         )

# test data
from sqlalchemy import MetaData, Column, Integer
from sqlalchemy.engine import create_engine
engine = create_engine('sqlite://')
metadata = MetaData(engine)
t = Table('t',
          metadata,
          Column('id', Integer, primary_key=True),
          Column('number', Integer))
t.create()
engine.execute(t.insert().values(id=1, number=3))
engine.execute(t.insert().values(id=9, number=-3))

# create view
createview = CreateView('viewname', t.select().where(t.c.id>5))
engine.execute(createview)

# reflect view and print result
v = Table('viewname', metadata, autoload=True)
for r in engine.execute(v.select()):
    print r

如果你愿意,你也可以专门学习一种方言,例如.

@compiles(CreateView, 'sqlite')
def visit_create_view(element, compiler, **kw):
    return "CREATE VIEW IF NOT EXISTS %s AS %s" % (
         element.name,
         compiler.process(element.select, literal_binds=True)
         )

Postgresql相关问答推荐

PostgreSQL:`row_alias为null`且`row_alias不是null`返回值不一致

PostgreSQL:函数结果表内冲突(...)上的";中的字段名称

如何在 postgresql 上使用 sqlalchemy 进行正确的 upsert?

Docker - 判断 postgres 是否准备好

Postgres/psycopg2 - 插入字符串数组

升级到 OSX Mavericks 后修复 postgresql

SELECT INTO 具有多个归因

什么是 postgres 超级用户

statement_date列是日期类型,但表达式是整数类型

PostgreSQL 不区分大小写的 SELECT 数组

Postgresql SERIAL 的工作方式是否不同?

从没有行的计数中获取 0 值

Postgres 外键on update和on delete选项如何工作?

使用 pg-promise 插入多条记录

Postgres NOT IN (null) 没有结果

在 postgresql 中,如何在 jsonb 键上返回布尔值而不是字符串?

在 Spring Boot 应用程序中禁用表重新创建

为 postgresql 存储过程设置隔离级别

如何在postgresql中编写关于最大行数的约束?

在 postgres 中导出为 CSV 并使用 GZIP 压缩