Flask SQLAlchemy — запрос представления с именованной схемой, отличной от стандартной. Каков наилучший подход?

#sqlalchemy #flask-sqlalchemy

#sqlalchemy #flask-sqlalchemy

Вопрос:

У меня есть view ( view1 ) в базе данных postgres ( dbtable ), с которой я хочу иметь возможность взаимодействовать с помощью Flask-SQLAlchemy.

Я попробовал несколько способов и столкнулся с ошибками. Я не уверен, вызывает ли проблему тот факт, что таблица / представление имеют именованную схему ( db_schema ), отличную от стандартной

Каков наилучший способ сделать это?


При следующей настройке:

 from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy

class Config:
    SQLALCHEMY_DATABASE_URI = "postgres://postgres:example@IP_ADDRESS:5432/dbtable"
    SQLALCHEMY_BINDS = {"db_key": SQLALCHEMY_DATABASE_URI},
    SQLALCHEMY_TRACK_MODIFICATIONS = False

app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
 

Я попытался выполнить запрос с помощью:

 str_query = """
        SELECT *
            FROM "view1"
            WHERE "date" > '{}'""".format(
    cutoff_date
)
resultproxy = db.engine.execute(str_query)
 

и получил эту ошибку:

 sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "view1" does not exist
LINE 3:                 FROM "view1"
                             ^

[SQL: 
            SELECT *
                FROM "view1"
                WHERE "date" > '2020-11-01']
(Background on this error at: http://sqlalche.me/e/f405)
 

Итак, я попытался добавить представление как объект, например:


Редактировать:

теперь указано определение таблицы и переопределено id как первичный ключ

Тем не менее, я все еще не могу запросить представление.

 class Table1(db.Model):
    __bind_key__ = "db_key"
    __tablename__ = "table1"

    __table_args__ = {"autoload": True, "autoload_with": db.engine, "schema": "db_schema"}
        
class View1(db.Model):
    #__bind_key__ = "db_key"
    #__tablename__ = "view1"
    
    #__table_args__ = {"autoload": True, "autoload_with": db.engine, "schema": "db_schema"}
    __table__ = Table('view1', db.Model.metadata,
             Column("id", String, primary_key=True), 
              Column("date", DateTime), 
              extend_existing=True,
                 info={'bind_key': 'db_key', "schema": "db_schema"})
    
    def get_all(self):
        items = self.query.all()
        return items
 

Когда я пытаюсь запросить

 view1 = View1()
items = view1.get_all()
 

Я получаю:

 TypeError: unhashable type: 'dict'
 

Комментарии:

1. Есть ли у вашего представления первичный ключ, или один или несколько его столбцов можно считать первичным ключом? Смотри сюда .

2. Я не думаю, что мое представление базы данных может иметь первичный ключ? Я попытался указать представление в виде таблицы и переопределил столбец, чтобы создать первичный ключ. Я все еще не могу выполнить запрос к нему. Отредактировал вопрос

3. Можете ли вы предоставить общий доступ к DDL для исходной таблицы и представления? Трудно точно знать, с чем мы здесь работаем.

4. Этот подход действительно работает, когда я включаю его в свой проект, просто не удалось в примере с игрушкой (не уверен, почему). Спасибо, что указали мне правильное направление