Flask-SQLAlchemy создает базу данных SQLite, но не таблицы - PullRequest
0 голосов
/ 30 сентября 2018

Я посмотрел на очень похожую проблему , но решение не работает для меня, и мне было интересно, могу ли я получить какое-то руководство.

Этомоя структура приложения:

mosiman/
  __init__.py
  blog/
    __init__.py
    blogconfig.py
    blog.py
    static/
      ...
    templates/
      ...

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

Вот, что я думаю, соответствующие файлы:

# mosiman/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import blog.blog as blog
...
...
db = SQLAlchemy()
...
...
def create_app():
    app = Flask(__name__)
    db_path = os.path.join(os.path.dirname(__file__), 'mosiman.db')
    app.config["SQLALCHEMY_DATABASE_URI"] = 'sqlite:///{}'.format(db_path)
    app.config["SQLALCHEMY_BINDS"] = {'blog': os.path.join(os.path.dirname(__file__), 'blog/blog.db')
    db.init_app(app)
    app.register_blueprint(blog.blog, url_prefix='/blog')
    return app
if __name__ == '__main__':
    app = create_app()
    app.run(debug=True)

У меня также есть в моем файле mosiman/blog/blog.py:

#mosiman/blog/blog.py
<<< all of the usual flask imports and SQLAlchemy, etc >>>
from .__init__ import db
blog = Blueprint('blog', __name__)
...
...
class Entry(db.Model):
    __bind_key__ = "blog"
    id = db.Column(db.Integer, primary_key = True)
    title = db.Column(db.String(150))
    ...
    ...

Вот моя проблема: я на самом деле неУ меня нет базы данных по умолчанию, поэтому у меня нет классов для нее.Но я хочу инициализировать базу данных моего блога с классом Entry.

Процедура по умолчанию для инициализации базы данных , похоже, заключается в том, чтобы вставлять в Python REPL, импортировать базу данных и запускать db.create_all()

Ну, я не могупросто импортируйте db и запустите db.create_all(), потому что db еще не был прикреплен к приложению (сделано в create_app()). Вот как я продолжаю:

# pop open a REPL at mosiman/
>>> from __init__ import db
>>> from __init__ import create_app
>>> app = create_app()
>>> db.init_app(app)
>>> from blog.blog import Entry
>>> db.init_app(app)
# At this point, db still isn't attached to an engine?
>>> db
<SQLAlchemy engine=None>
>>> with app.app_context():
...     db.create_all()
...
>>>

Теперь, когда я идуmosiman/blog/ Я обнаружил, что blog.db был создан, но когда я проверяю схему и таблицы в SQLite3, ничего не появляется.

1 решил их проблему, изменив from __init__ import db наfrom mosiman import db

Если я попытаюсь сделать это внутри mosiman/:

>>> from mosiman import db
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'mosiman'

, хотя там у меня есть __init__.py.

Если я запускаю его из ../ (каталог выше mosiman):

>>> from mosiman import db
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/users/d49chan/mosiman/__init__.py", line 3, in <module>
    import blog.blog as blog
ModuleNotFoundError: No module named 'blog'

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

1 Ответ

0 голосов
/ 30 сентября 2018

1) Вы не импортируете __init__.py.Вы должны импортировать его с именем каталога (пакета), в котором он находится.

2) Вы не должны импортировать так: import blog.blog.Вместо этого вы должны: from blog import blog.

3) Убедитесь, что у вас есть файл __init__.py в каждом каталоге, чтобы импортер python мог рассматривать его как пакет (каталог), из которого он может импортировать.

4) Существует разница между относительным импортом и абсолютным импортом.

Относительный импорт:

# l3_module.py in l3_package
from ..l1_package import l1_module

Импортирует модуль, расположенный на два пакета (каталоги) вверх относительно импорта модуля.it.

Теперь, предполагая, что l3_package находится в l2_package, который находится в l1_module, вы также можете импортировать его как таковой

Абсолютный импорт:

# l3_moudle.py in l3_package
from l1_package import l1_module

Это также будет работать, но иногда это все портит, в зависимости от вашей среды.Вот отличный ответ, который может прояснить некоторые вещи для вас: Относительный импорт в миллиардный раз .

Надеюсь, что помогло:)

...