PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment créer une vue SQL avec SQLAlchemy ?

Mise à jour : Voir aussi la recette d'utilisation de SQLAlchemy ici

La création d'une vue (en lecture seule non matérialisée) n'est pas prise en charge par défaut pour autant que je sache. Mais ajouter cette fonctionnalité dans SQLAlchemy 0.7 est simple (similaire à l'exemple que j'ai donné ici). Il vous suffit d'écrire une extension de compilateur CreateView . Avec cette extension, vous pouvez alors écrire (en supposant que t est un objet table avec une colonne 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

Voici un exemple fonctionnel :

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

Si vous le souhaitez, vous pouvez également vous spécialiser dans un dialecte, par exemple

@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)
         )