我正试图通过将模型、数据库、路由器等拆分为单独的文件来模块化我的flask应用程序。这给我带来了一些麻烦,因为我的表似乎没有像我预期的那样创建。
我有一个名为flask_postgres_server.py 的文件
from . import flask_server
from flask_sqlalchemy import SQLAlchemy
from flask import jsonify, request
from . import models
Tree = models.tree.Tree_postgres.Tree
app = flask_server.app # this simply exports an instance of a flask app, so I can use it in another server with mongo
@app.route("/trees", methods=['POST'])
def create_tree_postgres():
label = request.get_json['label']
tree = Tree(label=label)
tree.save()
return jsonify(tree.get_dict())
我正在导入Tree
型号:
from ... import postgres_db
db = postgres_db.db
class Tree(db.Model):
__tablename__ = 'trees'
id = db.Column(db.Integer, primary_key=True)
label = db.Column(db.String(), nullable=False)
def save(self):
db.session.add(self)
db.session.commit()
db.session.expunge_all()
db.session.close()
def get_dict(self):
return {"label": self.label, "_id": self.id}
然后导入db:
from . import flask_server
app = flask_server.app
import os
from dotenv import load_dotenv, find_dotenv
from flask_sqlalchemy import SQLAlchemy
"""
Imported by a server in order to set up a postgres connection for use by a Flask server
"""
load_dotenv(find_dotenv())
DB_NAME = os.environ.get("DB_NAME")
POSTGRES_HOST = os.environ.get("POSTGRES_HOST")
POSTGRES_PORT = os.environ.get("POSTGRES_PORT")
POSTGRES_USER = os.environ.get("POSTGRES_USER")
POSTGRES_PASSWORD = os.environ.get("POSTGRES_PASSWORD")
DB_URI = f'postgresql://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_HOST}:{POSTGRES_PORT}/{DB_NAME}'
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
db = SQLAlchemy(app)
db.create_all()
当我运行服务器并在/trees
上获取帖子数据时,我会收到以下错误消息:
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedTable) relation "trees" does not exist
LINE 1: INSERT INTO trees (label) VALUES ('countries') RETURNING tre...
^
[SQL: INSERT INTO trees (label) VALUES (%(label)s) RETURNING trees.id]
[parameters: {'label': 'countries'}]
这个关系不是应该自动创建的吗?
我可以进入psql并手动创建这个表。然后我得到另一个错误说:
DetachedInstanceError: Instance <Tree at 0x10d2facd0> is not bound to a Session
我构建代码的方式有问题吗?
Tree
模型之前调用了db.create_all()
,因此不会创建trees
表。
在问题中的代码中,可以通过将db.create_all()
移动到Tree
模型的定义之后来解决此问题。在您的整体结构中,db.create_all()
需要在所有模型定义执行完毕后调用(通常是通过导入包含它们的文件(。
请注意,关闭save
方法中的会话不是一个好主意——之后在调用get_dict
方法时将无法访问Tree
实例。我建议将会话生命周期管理留给烧瓶sqlalchemy,Tree.save
应该只有add
和commit
。
最后,路由处理程序中的label = request.get_json['label']
应该是label = request.get_json()['label']
。
DetachedInstanceError: Instance <Tree at 0x10d2facd0> is not bound to a Session
隐式地向用户提供线索,表明您创建的object 0x10d2facd0
已经"断开">与会话。
您已经关闭了与db.session.close()
的会话,但随后尝试访问";闭合的">对象。最好在关闭get_dict
结果之前保存它。它可以这样重写:
@app.route("/trees", methods=['POST'])
def create_tree_postgres():
label = request.get_json['label']
tree = Tree(label=label)
response = tree.get_dict()
tree.save()
return jsonify(response)