I started learning flask a few weeks ago and I followed flask mega tutorial. Now I want to do some programming myself and I tried to return data from database in json format using flask-marshmallow and I got stuck. I got an error saying ImportError: cannot import name fields.
This is full error message
This is models.py module:
followers = db.Table('followers',
db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
db.Column('followed_id', db.Integer, db.ForeignKey('user.id')))
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
country = db.Column(db.String(140))
nationality = db.Column(db.String(140))
password_hash = db.Column(db.String(128))
# Definisanje veze sa Post tabelom
posts = db.relationship('Post', backref='author', lazy='dynamic')
about_me = db.Column(db.String(140))
last_seen = db.Column(db.DateTime, default=datetime.utcnow())
# Definisanje veze sa followers tabelom
followed = db.relationship(
'User', secondary=followers,
primaryjoin=(followers.c.follower_id == id),
secondaryjoin=(followers.c.followed_id == id),
backref=db.backref('followers', lazy='dynamic'), lazy='dynamic')
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(140))
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return '<Post {}>'.format(self.body)
#Declaring marshmallow ModelSchema
class UserSchema(ma.ModelSchema):
class Meta:
model = User
This is routes.py module:
#app.route('/all_users', methods=['GET'])
def get_all_users():
users = User.query.all()
user_schema = UserSchema(many=True)
out = user_schema.dump(users).data
return jsonify(out)
I didn't include all code but I will provide it if it's necessary.
Since error message point me to microblog.py and init.py, also modules in my app, so I will include these two modules.
microblog.py
from app import app, db
from app.models import User, Post
#app.shell_context_processor
def make_shell_context():
return {'db': db, 'User': User, 'Post': Post}
__init__.py
from flask import Flask
from logging.handlers import RotatingFileHandler
import logging
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_mail import Mail
from flask_bootstrap import Bootstrap
from flask_moment import Moment
import os
'''Inicijalizacija ekstenzija'''
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)
login.login_view = 'login'
mail = Mail(app)
bootstrap = Bootstrap(app)
moment = Moment(app)
ma = Marshmallow(app)
from app import routes, models, errors
if not app.debug:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/microblog.log', maxBytes=10240,
backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Microblog startup')
Related
i have a project where i create four tables (users,products, agents, customer) when i do migration with:
flask db init,
flask db migrate,
flask db upgrade,
only users and products get migrated
here it is the structure of my project:
my code for user model is:
from main.extensions import db
from main.shared.base_model import BaseModel, HasCreatedAt,
HasUpdatedAt
class User(BaseModel, HasCreatedAt, HasUpdatedAt):
tablename = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String, unique=True, nullable=False)
password = db.Column(db.String, nullable=False)
phone = db.Column(db.Integer)
my code for every module starting by agent model:
from main.extensions import db
class Agent(db.Model):
__tablename__ = 'agents'
id = db.Column(db.Integer, primary_key=True)
picture = db.Column(db.String)
def __init__(self,email, password, phone, picture):
self.email = email
self.password=password
self.phone=phone
self.picture=picture
and for the model in customer is:
from main.modules.user.models import User
from main.extensions import db
class Customer(User):
__tablename__ = 'customers'
approved = db.Column(db.Boolean)
picture = db.Column(db.String)
def __init__(self, email, password, phone, picture, approved):
self.approved = approved
self.picture = picture
User.__init__(self,email,password,phone)
and finnaly the products model has:
from main.extensions import db
from main.shared.base_model import BaseModel, HasCreatedAt, HasUpdatedAt
class Product(BaseModel, HasCreatedAt, HasUpdatedAt):
__tablename__ = 'products'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
the settings.py contains the following code:
and this init files for every model contains this code:
for the user __init.py:
from main.modules.users.api import blueprint as api
for the customer __init.py:
from main.modules.customer.api import blueprint as api
for the agent__init.py:
from main.modules.agent.api import blueprint as api
for the prodcut__init.py:
from main.modules.product.api import blueprint as api
import os
class DevSettings(Settings):
DEBUG = True
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI="sqlite:///" + os.path.join(basedir, "data.sqlite")
SQLALCHEMY_TRACK_MODIFICATIONS=False
and the extension.py contains:
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
migrate = Migrate()
and the app.py contains this:
from flask import Flask, Blueprint
from main.extensions import db, migrate
from main.modules import product, agent, customer, user
from main.settings import DevSettings
MODULES = [ agent, customer,product, user]
main = Blueprint('main', __name__)
def create_app(settings=DevSettings):
app = Flask(__name__)
# Utiliser la configuration (settings).
app.config.from_object(settings)
app.config['SECRET_KEY'] = 'mysecretkey'
# On initialise les libraries Python.
# Init SQLAlchemy.
db.init_app(app)
# Init Migrate.
migrate.init_app(app, db)
app.register_blueprint(main)
register_modules(app)
return app
def register_modules(app):
for m in MODULES:
if hasattr(m, 'api'):
app.register_blueprint(m.api)
hello how can i solve this error.I have tried different answers provided for this error and it's still not working.
I am getting this error:
ArgumentError(
sqlalchemy.exc.ArgumentError: Could not parse rfc1738 URL from string 'api.db'
Here is my code:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_restless import APIManager
from sqlalchemy import MetaData
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///api.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
items = db.relationship('Item', backref='user', lazy='dynamic')
class Item(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20), unique=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
if __name__ == '__main__':
app.run(debug=True)
I am learning how to use SQLalchemy and databases in general with flask. I am following a tutorial and it uses the below classes and files.
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-iv-database
To show an inserted row in the database, the tutorial uses the following:
from app.models import User
>>> u = User(username='susan', email='susan#example.com')
>>> u
<User susan>
My problem is that I can not display the same output. I mean when I code the the statement, I get an error
from app.models import User
ImportError: No module named app.models
Please let me know how to adapt the posted code so I can retrieve data from database
Folder Structure:
d:\xxx\xxx\db1\app\models
d:\xxx\xxx\db1\__init__
d:\xxx\xxx\db1\config
** init **:
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
from app import routes, models
config:
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
# ...
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
models:
from app import db
from app.models import User
class User(db.Model):
id = db.Column(db.Integer, primaty_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
def __repr__(self):
return '<User {}>'.format(self.username)
You cannot import User on the same module where models is declared, so I don't think If you need that second line in models.py, Try commenting and see what happens
from app import db
from app.models import User ## I think the problems is
class User(db.Model):
id = db.Column(db.Integer, primaty_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
def __repr__(self):
return '<User {}>'.format(self.username)
I want to add images on my flaskblog posts, however, I am facing with the following error:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: post.post_image
[SQL: SELECT post.id AS post_id, post.title AS post_title, post.date_posted AS post_date_posted, post.content AS post_content, post.user_id AS post_user_id, post.post_image AS post_post_image
FROM post]
(Background on this error at: http://sqlalche.me/e/e3q8)
These are my imports in routes.py file
import os
import secrets
from PIL import Image
from flask import render_template, url_for, flash, redirect, request, abort
from flaskblog import app, db, bcrypt
from flaskblog.forms import RegistrationForm, LoginForm, UpdateAccountForm, PostForm
from flaskblog.models import User, Post
from flask_login import login_user, current_user, logout_user, login_required
This is my new_post function and new post route in routes.py file
#app.route("/post/new", methods=['GET', 'POST'])
#login_required
def new_post():
form = PostForm()
if form.validate_on_submit():
if form.post_picture.data:
image_post = save_picture(form.picture.data)
form.post_picture = image_post
post = Post(title=form.title.data, content=form.content.data, author=current_user, post_image= form.post_picture.data)
db.session.add(post)
db.session.commit()
flash('Your post has been created!', 'success')
return redirect(url_for('home'))
image_file = url_for('static', filename='profile_pics/')
return render_template('create_post.html', title='New Post', image_file=image_file,
form=form, legend='New Post')
This is my imports in form.py file
from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed
from flask_login import current_user
from wtforms import StringField, PasswordField, SubmitField, BooleanField, TextAreaField
from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError
from flaskblog.models import User
this is my PostForm class in forms.py file
from datetime import datetime
from flaskblog import db, login_manager
from flask_login import UserMixin
#login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.image_file}')"
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
post_image = db.Column(db.String(20), nullable=False)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
regarding these codes, what do you think I should do in order to fix this error? Thank you.
edit1:
This is my init.py file
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from flask_login import LoginManager
app = Flask(__name__)
app.config['SECRET_KEY'] = '5791628bb0b13ce0c676dfde280ba245'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login'
login_manager.login_message_category = 'info'
from flaskblog import routes
edit2: I am having the following error after dropping tables from the db.
This is the blog post view
Have you newly added the post_image field to the Post model?
If so, you'd need to either
use a database migration tool like Alembic to generate and apply the SQL statements to alter the table, or
add the suitable column into the table by hand (tedious), or
drop the table and recreate it (destroying all data; dangerous)
I am new to Flask/MYSQLAlchemy/Postgres and am still trying to understand it all.
I have got an app:
from flask import Flask
from flask_cors import CORS
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
def create_app(*args, app_name="SMARRTBROKER_API"):
# add sentry integration
sentry_sdk.init(
dsn="https://cd31f9dbcd56420fa0ca08422a441747#sentry.io/1369455",
integrations=[FlaskIntegration()]
)
app = Flask(app_name)
CORS(app, resources=r'/api/*')
# CORS(app, resources={r"/api/*": {"origins": "*"}}, supports_credentials=True)
app.config.from_object('api.config.DevelopmentConfig')
from api.api import api
app.register_blueprint(api, url_prefix='/api')
# app.config['SQLALCHEMY_ECHO'] = True
from api.models import db
db.init_app(app)
return app
And a manage.py file:
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from api.application import create_app
from api.models import db, Lead, User, Setting, Category, Keyword, keyword_identifier, Product, Plan
from filter_class import Filter
from filter_keyword import FilterKeyword
from sqlalchemy.dialects.postgresql import array
from sqlalchemy import or_, not_
from sqlalchemy import any_
from datetime import datetime, timedelta
from sqlalchemy.orm.attributes import flag_modified
from classification import Classification
app = create_app()
migrate = Migrate(app, db)
manager = Manager(app)
# provide a migration utility command
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
And a model.py file:
"""
models.py
Data classes for the api application
"""
from datetime import datetime
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from sqlalchemy.ext.mutable import Mutable
from sqlalchemy.dialects.postgresql import ARRAY
import enum
import locale
db = SQLAlchemy()
...
class Setting(db.Model):
__tablename__ = 'settings'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow)
import_settings = db.Column(db.JSON, nullable=True)
def to_dict(self):
return dict(
id=self.id,
name=self.name,
created_at=self.created_at,
label=self.label
)
class Keyword(db.Model):
__tablename__ = 'keywords'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text, nullable=False)
label = db.Column(db.Text, nullable=False, unique=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
updated_at = db.Column(db.DateTime, default=datetime.utcnow)
leads = db.relationship('Lead', secondary=keyword_identifier)
def to_dict(self):
return dict(
id=self.id,
label=self.label,
name=self.name,
created_at=self.created_at
)
...
And up until a couple weeks ago, if I made any change in the models file, I could run python manage.py db migrate and python manage.py db upgrade and the models were amended and the migration would take place without problems. Now, for whatever reason, when I run the migrate/upgrade commands, nothing happens and it seems that my changes were not recognised at all. Any ideas of why?