[英]SQLAlchemy Create View in PostgresQL
我正在尝试使用SQLAlchemy和Postgresql作为基础数据库创建视图。 单独的用于创建视图的选择查询可以很好地工作并返回结果,但是当我在创建视图中使用它时,会出现错误sqlalchemy.exc.NoSuchTableError:流行,这意味着未选择视图。 尝试从视图中选择时出现错误。 创建视图不会引发任何错误,但不会创建视图。 这是我的代码:
from sqlalchemy import *
import sqlalchemy as db
from sqlalchemy import func
from sqlalchemy import desc
from sqlalchemy import Table
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Executable, ClauseElement
try:
engine = db.create_engine('postgresql://user:pass@localhost:5432/db_name')
connection = engine.connect()
except:
print('Error establishing DB connection')
# Import metadata
metadata = db.MetaData()
# Import articles, authors and log tables
art = db.Table('articles', metadata, autoload=True, autoload_with=engine)
aut = db.Table('authors', metadata, autoload=True, autoload_with=engine)
log = db.Table('log', metadata, autoload=True, autoload_with=engine)
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)
)
# Method to create view with top three articles
def view_top_three():
top_three_view = CreateView('popular', db.select([art.columns.title, func.count(log.columns.path)]) \
.where(func.concat('/article/', art.columns.slug) == log.columns.path) \
.where(log.columns.path != "/") \
.group_by(log.columns.path, art.columns.title) \
.order_by(desc(func.count(log.columns.path))) \
.limit(3))
engine.execute(top_three_view)
v = Table('popular', metadata, autoload=True, autoload_with=engine)
for r in engine.execute(v.select()):
print(r)
# Call the method which creates view and selects from view
view_top_three()
任何帮助将不胜感激。
由于您的CreateView
继承自Executable
和ClauseElement
,因此不被视为数据更改操作。 换一种说法
engine.execute(top_three_view)
当连接返回到池时,执行CREATE VIEW
语句,然后隐式回滚。
相反,它应该是DDLElement
的子类,如用法食谱Wiki中所示 。 只需更改基类,即可使SQLAlchemy自动提交正常工作。
我找到了解决方案。 问题与自动提交有关。 在创建引擎时将autocommit设置为true可解决以下问题:
engine = db.create_engine('postgresql://user:pass@localhost:5432/db_name').execution_options(autocommit=True)
特别提及@ilja-everilä
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.