11

我想使用Flask-Migrate并查看他们的示例:

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

db = SQLAlchemy(app)
migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))

if __name__ == '__main__':
    manager.run()

这作为一个简单的播放示例非常有用,但我有不止一个模型,我不想在这个脚本和定义我的应用程序代码的脚本中定义模型。因此,我想将它们拉入一个模型文件中,以便在两者之间共享。

我试图通过将User类放入 amodels.py然后从那里导入 User 来做到这一点。不幸的是,这会引发NameError: name 'db' is not defined.

我的问题是:

  • 我是否需要db = SQLAlchemy(app)在我的 中使用models.py,如果需要,我的迁移脚本和烧瓶应用程序本身都可以使用它吗?
  • 如果我不能(或不应该)把它放进去models.py,我如何在他们自己的文件中使用我的模型而不会db全部通过?
4

3 回答 3

21

将这么小的应用程序划分为模块很棘手,因为您会发现很多情况下,您创建的两个模块需要相互导入,从而创建循环依赖关系。

我建议您查看如何正确构建更大的应用程序,使用应用程序工厂功能和延迟初始化所有扩展。执行此操作的示例应用程序是我书中介绍的Flasky应用程序。

综上所述,可以将应用程序分成两部分,您只需要注意放置导入语句的位置。在下面的示例中,我决定将db实例和User模型的创建移动到 models.py 文件中。

这是主应用程序的模块:

from flask import Flask
from flask.ext.script import Manager
from flask.ext.migrate import Migrate, MigrateCommand

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'

from models import db  # <-- this needs to be placed after app is created
migrate = Migrate(app, db)

manager = Manager(app)
manager.add_command('db', MigrateCommand)

if __name__ == '__main__':
    manager.run()

这是models.py:

from __main__ import app
from flask.ext.sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))

在这里主模块将创建app,然后才会导入models.py。当 models.py 尝试app从主模块导入时,它已经被创建了。如果您from models import db使用其他导入移动到文件顶部,则此代码会中断。

于 2015-12-15T16:42:10.843 回答
1

这是一个想法。您可以创建一个包model,在其中将类定义为单个.py文件。例如,user.py包含User类。

__init__.py文件中,您可以定义db变量。您还可以包含from user import User语句,以便可以User直接在包外访问对象。例如,您可以在程序的model其他地方使用导入包import model,然后使用model.User直接使用User该类。

db直接在使用文件中定义的导入变量中user.py使用变量。from ..model import dbdb__init__.py

于 2015-12-15T05:56:23.037 回答
0

你的回答对我很有帮助。我终于掌握了相当繁琐的python导入规则。在这里,我尝试以一种更简洁的方式来说明该模式(“更简洁”是指不复杂的其他问题,例如迁移问题)。这是将应用程序划分为仅声明数据库模型的主模块和辅助模块的简单且常见的情况。

主要的:

from flask import Flask, render_template, request, url_for, redirect
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__) # this is a key point

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///clientes.sqlite3'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 
app.config['SECRET_KEY'] = "random string"

from fasiDB import db, Corr, Cliente, Producto # db and models

# here come the various routes which access db

楷模:

from __main__ import app
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy(app) # the argument "app" comes from main

class Corr(db.Model):
    id = db.Column('corr_id', db.Integer, primary_key=True)
    nf = db.Column(db.Integer)

...

class Cliente(db.Model):
   id = db.Column('cliente_id', db.Integer, primary_key = True)
   nombre = db.Column(db.String(64), unique=True)
   rSocial = db.Column(db.String(64), unique=True)
   ruc = db.Column(db.String(27), unique=True)
   dir = db.Column(db.String(100))

...

于 2021-09-06T20:44:28.697 回答