Sqlalchemy递归视图工厂不在DB中创建视图

时间:2016-06-16 17:58:54

标签: python postgresql sqlalchemy pyramid

我试图让sqlalchemy创建一个递归视图。如果视图已经创建,代码似乎适用于查询,但在尝试创建视图时会抛出错误。

  

sqlalchemy.exc.ProgrammingError:(psycopg2.ProgrammingError)语法错误在" AS"   第1行:创建RECURSIVE VIEW device_type_hierarchy AS无                                                       ^    [SQL:' CREATE RECURSIVE VIEW device_type_hierarchy AS None']

selectable中必定存在导致语句无法编译的内容,但我无法看到它。我有一个类似的工厂,它创建一个物化视图,它工作正常。

有什么想法吗?

recursive_view_factory.py

# Example from https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/Views

from sqlalchemy.ext import compiler
from sqlalchemy.schema import DDLElement
from sqlalchemy.sql import table
import sqlalchemy as db


class CreateRecursiveView(DDLElement):
    def __init__(self, name, selectable):
        self.name = name
        self.selectable = selectable


class DropRecursiveView(DDLElement):
    def __init__(self, name):
        self.name = name


@compiler.compiles(CreateRecursiveView)
def compile(element, compiler, **kw):
    return "CREATE RECURSIVE VIEW %s AS %s" % (element.name, compiler.sql_compiler.process(element.selectable))

@compiler.compiles(DropRecursiveView)
def compile(element, compiler, **kw):
    return "DROP VIEW %s" % (element.name)

def recursive_view(metadata, name, selectable):
    #_mt = db.MetaData() # temp metadata just for initial Table object creation
    #t = db.Table(name, _mt)
    t = table(name)

    for c in selectable.c:
        c._make_proxy(t)

    db.event.listen(metadata,
                    "after_create",
                    CreateRecursiveView(name, selectable)
    )

    db.event.listen(metadata,
                    "before_drop",
                    DropRecursiveView(name)
    )
    return t

model.py

class TDeviceType(Base):
    __tablename__ = 'tDeviceType'
    label = 'Device Type'
    plural = 'Device Types'

    ixDeviceType = Column(Integer, primary_key=True)
    ixParentDeviceType = Column(Integer, ForeignKey('tDeviceType.ixDeviceType'), nullable=True)
    sDeviceType = Column(Unicode(255),
                         info={'label' : 'Device Type'})

class RVDeviceTypeHierarchy(Base):
    included_devices = (select([TDeviceType.ixDeviceType.label('ixDeviceType'),
                                TDeviceType.ixParentDeviceType.label('ixParentDeviceType'),
                                TDeviceType.sDeviceType.label('sDeviceType'),
                                cast(func.row_number().over(partition_by=TDeviceType.ixParentDeviceType,
                                                            order_by=TDeviceType.sDeviceType),
                                     Unicode).label('path')])
                        .select_from(TDeviceType)
                        .where(TDeviceType.ixParentDeviceType is None)
                        .cte(name="device_type_hierarchy", recursive=True))
    incl_alias = included_devices.alias()
    dt_alias = orm.aliased(TDeviceType, name='i')

    dth = (included_devices.union_all(
        select([dt_alias.ixDeviceType.label('ixDeviceType'),
                dt_alias.ixParentDeviceType.label('ixParentDeviceType'),
                dt_alias.sDeviceType.label('sDeviceType'),
                func.concat(included_devices.c.path,
                            cast(func.row_number().over(partition_by=dt_alias.ixParentDeviceType,
                                                        order_by=dt_alias.sDeviceType),
                                 Unicode)).label('path')])
        .select_from(join(dt_alias,
                          included_devices,
                          included_devices.c.ixDeviceType == dt_alias.ixParentDeviceType))))

    __table__ = recursive_view(metadata,
                               "device_type_hierarchy",
                               dth)

0 个答案:

没有答案