Flask create_app не будет инициализировать расширение экземпляра БД при инициализации

#python #postgresql #flask #psycopg2

#python #postgresql #flask #psycopg2

Вопрос:

В приведенных ниже двух фрагментах кода первый работает нормально, когда я создаю объект подключения, который импортируется из приложения, но не в методе create_app(). его глобальный. Однако, когда я создаю класс DB и пытаюсь выполнить шаги для создания экземпляра в create_app(). это не работает, любая помощь приветствуется. Это работает отлично

 import os
from flask import Flask, current_app
import psycopg2
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_script import Manager
from flask_mail import Mail
from Flask_blog.database_queries import *
from Flask_blog.config import Config

connection = psycopg2.connect("postgres://postgres:postgres...url")
bcrypt = Bcrypt()
login_manager = LoginManager()
login_manager.login_view = 'users.login'
login_manager.login_message_category = 'info'
mail = Mail()

#to run scripts or functions at start-up
script_manager = Manager()
script_manager.add_command('setup_database', Initial_checks(connection))


def create_app(config_class=Config):

    app = Flask(__name__) #app variable being set an Instance of Flask class
    app.config.from_object(Config)

    bcrypt.init_app(app)
    login_manager.init_app(app)
    mail.init_app(app)
    script_manager(app)

    from Flask_blog.users.routes import users
    from Flask_blog.posts.routes import posts
    from Flask_blog.main.routes import main

    app.register_blueprint(users)
    app.register_blueprint(posts)
    app.register_blueprint(main)
    return app
 

Когда я пытаюсь создать класс psycopg2 DB и создать расширение, как с другими плагинами, оно не работает с какой-либо ошибкой. Это не работает

 import os
from flask import Flask, current_app
import psycopg2
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
from flask_script import Manager
from flask_mail import Mail
from Flask_blog.database_queries import *
from Flask_blog.config import Config
    
#CREATING THIS CLASS FOR DB
class PostgresConnection(object):
    
    def __init__(self):
        self.connection = None

    def init_app(self, app):
            #self.connection = psycopg2.connect(app.config['POSTGRES_URL'])
            self.connection = psycopg2.connect("postgres://postgres:....url")

bcrypt = Bcrypt()
login_manager = LoginManager()
login_manager.login_view = 'users.login'
login_manager.login_message_category = 'info'
mail = Mail()
connection = PostgresConnection() # CREATING EXTENSION

#to run scripts or functions at start-up
script_manager = Manager()
script_manager.add_command('setup_database', Initial_checks(connection))


def create_app(config_class=Config):

    app = Flask(__name__) #app variable being set an Instance of Flask class
    app.config.from_object(Config)

    #connectioned = psycopg2.connect(app.config['POSTGRES_URL'])
    #connection = connectioned

    bcrypt.init_app(app)
    login_manager.init_app(app)
    mail.init_app(app)
    script_manager(app)
    connection.init_app(app) #####


    from Flask_blog.users.routes import users
    from Flask_blog.posts.routes import posts
    from Flask_blog.main.routes import main

    app.register_blueprint(users)
    app.register_blueprint(posts)
    app.register_blueprint(main)
    return app
 

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

   File "d:project7Flask_blogdatabase_queries.py", line 6, in Run_Query
    with connection:
AttributeError: __enter__
 

Ответ №1:

Ваши фрагменты не показывают, откуда Initial_checks они берутся.

Похоже, он пытается использовать connection в качестве контекстного менеджера.

В первом случае это работает, потому что ему передается возвращаемое значение psycopg2.connect .

Во втором случае (init_app) это не работает, потому что

  • вы передаете ему PostgresConnection экземпляр, а не connection атрибут
  • connection атрибут в любом случае не устанавливается во время импорта

Проблема заключается в том, что вы вызываете Initial_checks во время импорта, в то время как ваше соединение может быть готово только во время инициализации приложения.

Эти проверки следует отложить до времени инициализации.

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

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