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()

これは単純な play の例としてはうまく機能しますが、モデルが複数あるため、このスクリプトとアプリケーション コードを定義するスクリプトの両方でモデルを定義したくありません。したがって、2 つの間で共有できるモデル ファイルにそれらを取り込みたいと考えています。

Userクラスをに配置しmodels.py、そこから User をインポートすることで、これを実行しようとしています。残念ながら、それはNameError: name 'db' is not defined.

私の質問は次のとおりです。

  • db = SQLAlchemy(app)で使用する必要がありmodels.pyますか? もしそうなら、これは移行スクリプトとフラスコ アプリケーション自体の両方で利用できますか?
  • に入れられない (または入れるべきではない) 場合、models.py自分のモデルを独自のファイルで使用する方法を教えてくださいdb
4

3 に答える 3

21

このような小さなアプリケーションをモジュールに分割するのは注意が必要です。なぜなら、作成する 2 つのモジュールが相互にインポートする必要があり、循環依存関係を作成する必要がある場合が多いからです。

アプリ ファクトリ関数とすべての拡張機能の遅延初期化を使用して、より大きなアプリケーションを適切に構築する方法を検討することをお勧めします。これを行うアプリケーションの例は、私の本で紹介されているFlaskyアプリです。

とはいえ、アプリケーションを 2 つの部分に分けることは可能ですが、インポート ステートメントを配置する場所に注意する必要があります。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.pyappがメイン モジュールからインポートしようとすると、既に作成されています。from models import db他のインポートでファイルの先頭に移動すると、このコードが壊れます。

于 2015-12-15T16:42:10.843 に答える
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 に答える