问题
I am trying to build a simple blogging platform to learn Python and Flask. I am using SQLAlchemy to connect to a Postgres db hosted on Heroku and flask_s3 to serve static files from an AWS bucket. Im mostly following along from this:
https://gist.github.com/mayukh18/2223bc8fc152631205abd7cbf1efdd41/
All was going well, it is correctly hosted on Heroku and connceted to AWS S3 bucket, ready to go. I am stuck however on how to add blog posts to the database through some kind of form or route that will allow me to fill in the attributes of a blog post (found in Post in models.py below)
I have html templates that get rendered and the following three files, app.py, manage.py and models.py.
app.py:
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from flask_s3 import FlaskS3
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = '*URI for DB hosted on heroku'
app.config['FLASKS3_BUCKET_NAME'] = 'my S3 bucket on AWS'
db = SQLAlchemy(app)
s3 = FlaskS3(app)
from models import Post
#routes to templates to be rendered
if __name__ == '__main__'
app.run(debug=True)
manage.py:
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from app import app, db
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
and models.py:
from manage import db,app
class Post(db.Model):
__tablename__ = 'blogposts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(120), index=True, unique=True)
content = db.Column(db.Text, index=True, unique=True)
date = db.Column(db.DateTime, index=True, unique=True)
tag = db.Column(db.String(120), index=True, unique=True)
cover = db.Column(db.String(120), index=True, unique=True)
def __repr__(self):
return '<Post: %r>' % (self.title)
my file strucure is:
-blog
--__pycache__
--migrations
--static
--templates
app.py
manage.py
models.py
Pipfile
Pipfile.lock
Procfile
I want to work on this locally (before I publish anything to Heroku) but have no idea what to do from here. Anyone have advice on how to go about creating a route to add blog posts and saving them to a local Postgres instance before I go about pushing finalized blog posts to Heroku?
the gist I have been following has something like this as a route:
@app.route('/add/')
def webhook():
#post attributes defined
p = Post(id = id, title = title, date = datetime.datetime.utcnow, content = content, tag = tag, cover = cover)
print("post created", p)
db.session.add(p)
db.session.commit()
return "post created"
when I try and run it locally I get the following error so I'm not sure I have the files connecting properly.
File "/Users/Mb/Desktop/datadude/app.py", line 15, in <module>
from models import Post
ImportError: cannot import name 'Post'
Sorry if this is the wrong place for this. If there is a better place to ask for advice let me know.
回答1:
The problem exists in circular dependencies.
You could move initializing of SQLAlchemy to models.py. Then only run method init_app on db object in app.py.
models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Post(db.Model):
__tablename__ = 'blogposts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(120), index=True, unique=True)
content = db.Column(db.Text, index=True, unique=True)
date = db.Column(db.DateTime, index=True, unique=True)
tag = db.Column(db.String(120), index=True, unique=True)
cover = db.Column(db.String(120), index=True, unique=True)
def __repr__(self):
return '<Post: %r>' % (self.title)
app.py
import datetime
from flask import Flask, render_template
from flask_s3 import FlaskS3
from models import db
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = '*URI for DB hosted on heroku'
app.config['FLASKS3_BUCKET_NAME'] = 'my S3 bucket on AWS'
db.init_app(app)
s3 = FlaskS3(app)
from models import Post
@app.route('/add/')
def webhook():
#post attributes defined
p = Post(id = id, title = title, date = datetime.datetime.utcnow, content = content, tag = tag, cover = cover)
print("post created", p)
db.session.add(p)
db.session.commit()
return "post created"
#routes to templates to be rendered
if __name__ == '__main__':
app.run(debug=True)
You can read more about it https://github.com/slezica/bleg/blob/master/data/posts/2014-03-08-avoiding-circular-dependencies-in-flask.md
来源:https://stackoverflow.com/questions/51756650/using-proper-file-structure-with-sqlalchemy-and-how-to-add-data-to-db