不能 create/open SQLite 数据库

Can't create/open SQLite database

我正在尝试制作一个基本的 Flask - SQLAlchemy 应用程序。 我不明白 Flask Facory 系统如何与 Flask-SQLAlchemy 一起工作。 这是我的 __init__.py 文件:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

def create_db(app: Flask):
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///instance/pdfextractor.db'
    db = SQLAlchemy(app)
    from pdfextractor.models import FileModel
    db.init_app(app)
    db.create_all()
    db.session.commit()

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_pyfile('config.py', silent=False)
        app.config.update(test_config)

    create_db(app)

    from pdfextractor import router
    app.register_blueprint(router.bp)

    return app

唯一的异常结果:RuntimeError 未找到应用程序。

要么在视图函数内部工作,要么推送应用程序上下文。参见 flask-sqlalchemy.pocoo.org/contexts.

文件“pdfextractor/__init__.py”,第 20 行,在 create_db db.create_all()

文件“pdfextractor/__init__.py”,第 42 行,在 create_app create_db(app)

文件FileModel.py:

import pdftotext
from datetime import datetime
from pathlib import Path
from flask import current_app as app
from shutil import copyfile
from flask_sqlalchemy import SQLAlchemy  

db = SQLAlchemy()

class FileModel(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(), unique=True, nullable=False)
    datetime = db.Column(db.String(255), unique=True, nullable=False)

    def __init__(self: object, content=None, datetime=None):
        self.content = content
        self.datetime = datetime

        self._output_folder = Path(app.config['DATA_FOLDER'])
        if False == self._output_folder.exists():
            self._output_folder.mkdir()
    
    def __repr__(self):
        return '<File %r>' % (self.content, self.datetime)

非常感谢您的支持!

我已使用以下代码解决了我的问题。感谢您的帮助!

__init__.py

from flask import Flask

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_pyfile('config.py', silent=False)
        app.config.update(test_config)

    from pdfextractor import router
    app.register_blueprint(router.bp)

    return app

FileModel.py

import pdftotext
from datetime import datetime
from pathlib import Path
from flask import current_app as app
from sqlalchemy import Column, Integer, String
from pdfextractor.common.base import Base
from pdfextractor.common.base import session_factory

class FileModel(Base):
    __tablename__ = 'file'
    id=Column(Integer, primary_key=True)
    content=Column('content', String)
    datetime=Column('datetime', String(255))

    def __init__(self: object, content=None, datetime=None):
        self.content = content
        self.datetime = datetime

        self._output_folder = Path(app.config['DATA_FOLDER'])
        if False == self._output_folder.exists():
            self._output_folder.mkdir()

    def _persist(self, content: str, datetime: str):
        session = session_factory()
        self.content = str(content)
        self.datetime = str(datetime)
        session.add(self)
        session.commit()
        session.close()

    def persist(self, filename: str):
        today = datetime.today()
        output_filepath = self._output_folder / Path('file_' + today.strftime("%Y-%m-%d-%H-%M-%S.%f") + '.txt')

        if "pdf" == filename.rsplit('.', 1)[1].lower():
            with open(filename, "rb") as f:
                data = pdftotext.PDF(f)
                with open(output_filepath, 'w') as f:
                    f.write('\n'.join(data))
                    self._persist(''.join(data), output_filepath)
                    return 0
        return -1

base.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///instance/pdfextractor.db')
# use session_factory() to get a new Session
_SessionFactory = sessionmaker(bind=engine)

Base = declarative_base()

def session_factory():
    Base.metadata.create_all(engine)
    return _SessionFactory()