2017-07-17 12 views
1

sqlalchemy create tablesに記載されているソリューションを試しましたが、フラスコのドキュメントhttp://flask-sqlalchemy.pocoo.org/2.1/contexts/も参照してください。私は、create_all()を使ってデータベーステーブルを作成する際に問題に直面しています。ここに私のコードです。 postgresのオンsqlalchemyテーブルにメタデータをバインドする方法

>>> from flask import Flask 
>>> app = Flask('myflaskapp') 
>>> from flask_sqlalchemy import SQLAlchemy 
>>> app.url_map.strict_slashes = False 
>>> app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql+psycopg2://my_dbuser:[email protected]/my_dev_db' 
>>> app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 
>>> from myflaskapp.models import AdRequest, AdResult 
>>> AdRequest.__table__ 
Table('ad_request', MetaData(bind=None), Column('id', Integer(), table=<ad_request>, primary_key=True, nullable=False), Column('status', String(length=10), table=<ad_request>, default=ColumnDefault('NEW')), Column('status_msg', String(length=100), table=<ad_request>, default=ColumnDefault('')), Column('query_str', String(length=100), table=<ad_request>), schema=None) 
>>> db = SQLAlchemy(app) 
>>> db.engine 
Engine(postgresql+psycopg2://my_dbuser:***@localhost/my_dev_db) 
>>> db.metadata.create_all(db.engine) 
>>> db.engine 
Engine(postgresql+psycopg2://my_dbuser:***@localhost/my_dev_db) 
>>> db 
<SQLAlchemy engine=postgresql+psycopg2://my_dbuser:***@localhost/my_dev_db> 
>>> db.session.commit() 

「\ DTを」コンソールcreate_allを実行した結果として作成されるはずです新しいテーブルad_requestは表示されません。

さらに、私はapp ['SQLALCHEMY_ECHO'] = Trueとデバッグを追加しました。私は解読できない以下の出力を取得します。

>>> app.config['SQLALCHEMY_ECHO']=True 
>>> from models import * 
>>> with app.app_context(): 
... db.create_all() 
... 
2017-07-17 10:24:09,766 INFO sqlalchemy.engine.base.Engine select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where pg_catalog.pg_table_is_visible(c.oid) and relname=%(name)s 
2017-07-17 10:24:09,766 INFO sqlalchemy.engine.base.Engine {'name': 'ad_request'} 
2017-07-17 10:24:09,768 INFO sqlalchemy.engine.base.Engine select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where pg_catalog.pg_table_is_visible(c.oid) and relname=%(name)s 
2017-07-17 10:24:09,769 INFO sqlalchemy.engine.base.Engine {'name': 'ad_result'} 
2017-07-17 10:24:09,772 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE ad_request (
    id SERIAL NOT NULL, 
    status VARCHAR(10), 
    status_msg VARCHAR(100), 
    query_str VARCHAR(100), 
    PRIMARY KEY (id) 
) 
2017-07-17 10:24:09,772 INFO sqlalchemy.engine.base.Engine {} 
2017-07-17 10:24:09,779 INFO sqlalchemy.engine.base.Engine COMMIT 
2017-07-17 10:24:09,780 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE ad_result (
    id SERIAL NOT NULL, 
    uuid_s VARCHAR(50), 
    score FLOAT, 
    ad_request_id INTEGER, 
    PRIMARY KEY (id), 
    FOREIGN KEY(ad_request_id) REFERENCES ad_request (id) 
) 
2017-07-17 10:24:09,780 INFO sqlalchemy.engine.base.Engine {} 
2017-07-17 10:24:09,784 INFO sqlalchemy.engine.base.Engine COMMIT 

私はAdRequestに気付きました。 表( 'ad_request' を示し、メタデータ(バインド=なし)は、... にはどうすればdb.metadataにAdRequestバインドを行うことができますか? 続いたときに

# models.py 
from flask_sqlalchemy import SQLAlchemy 
from flask_marshmallow import Marshmallow 


db = SQLAlchemy() 
ma = Marshmallow() 


class AdRequest(db.Model): 
    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 
    status = db.Column(db.String(10), default="NEW") 
    status_msg = db.Column(db.String(100), default="") 
    query_str = db.Column(db.String(100)) 

    def __init__(self, query_str): 
     self.query_str = query_str 

    def __repr__(self): 
     return '<AdRequest %r, %r, %r, %r>' % (self.id, self.query_str, self.status, self.status_msg) 

    def as_dict(self): 
     return {'id': self.id, 
       'query_str': self.query_str, 
       'status': self.status, 
       'status_msg': self.status_msg, 
       } 


class AdResult(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    uuid_s = db.Column(db.String(50)) 
    score = db.Column(db.Float) 
    ad_request_id = db.Column(db.Integer, db.ForeignKey('ad_request.id')) 

    def __init__(self, uuid_s, score, ad_request_id): 
     self.uuid_s = uuid_s 
     self.score = score 
     self.ad_request_id = ad_request_id 

    def __repr__(self): 
     return '<AdResult %r, %r, %s>' % (self.id, self.uuid_s, self.ad_request_id) 


class AdRequestSchema(ma.Schema): 
    class Meta: 
     # Fields to expose 
     fields = ('id', 'status', 'status_msg', 'query_str') 
+0

'models'ファイルには何がありますか?どのようにしてテーブルのメタデータを取得しますか? – krassowski

+0

models.py – ryk

答えて

0

注文事項私のmodels.pyですあなたがモデルを宣言するときと使用するときに同じSQLAlchemyインスタンスを使用する必要があります。例えば、モデルファイルで1回、Pythonコンソールで1回、データベースを2回作成します。

database.pyという2つの行を持つ別のファイルを作成します。

お使いのモデルに続いて
from flask_sqlalchemy import SQLAlchemy 
db = SQLAlchemy() 

それをインポートし、モデルのベースとして使用します。

from database import db 

class AdRequest(db.Model): 
    id = db.Column(db.Integer, primary_key=True, autoincrement=True) 

# rest of your models file 

としてアプリを作成します。

from flask import Flask 
from database import db 
from models import AdRequest, AdResult 

app = Flask('myflaskapp') 
app.url_map.strict_slashes = False 

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db' 
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False 

with app.app_context(): 
    db.init_app(app) # this is important! 
    db.create_all() 

それが助け場合は私に知らせてください。

編集:コードを実行して、test.dbファイルが作成されているかどうかチェックすることで、コードが機能しているかどうかを確認できます。ファイルが存在していても問題が残っている場合、おそらくPostgreSQL固有の問題です。

+0

ありがとうございました。 – ryk

関連する問題