首页 文章

sqlalchemy如何将元数据绑定到表

提问于
浏览
1

我已经尝试了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 . table 显示表('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')

1 回答

  • 0

    对于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特定的问题 .

相关问题