我已经尝试了sqlalchemy create tables中提到的解决方案,并且还提到了烧瓶文档http://flask-sqlalchemy.pocoo.org/2.1/contexts/。我在使用create_all()创建数据库表时遇到问题。这是我的代码。
>>> 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:my_dbuser_password@localhost/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()
在postgres控制台上,“\ 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',MetaData(bind =无),... 如何将AdRequest绑定到db.metadata? 以下是我的models.py
# 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 :(得分:1)
对于SQLAlchemy来说,顺序很重要。在声明模型和使用它们时,必须使用相同的SQLAlchemy实例。在您提供的示例中,您创建了两次数据库 - 一次在模型文件中,一次在Python控制台中。
只需创建一个名为 database.py 的单独文件,其中包含两行:
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特定问题。