AttributeError: sqlalchemy object has no attribute "Models" error is occurring. I already installed all requirements like pip install sqlalchemy, flask-sqlalchemy, psycopy2-binary. this file name is create.py
import os
from flask import Flask, render_template, request
from models import *
app = Flask(__name__)
app.config["SQLALchemy_DATABASE_URI"] = os.getenv("DATABASE_URL")
app.config["SQLALchemy_TRACK_MODIFICATIONS"] = False
db.init_app(app)
def main():
db.create_all()
if __name__ == "__main__":
with app.app_context():
main()
this file is models.py
from flask_sqlalchemy import SQLAlchemy
db=SQLAlchemy()
class Flight(db.Models):
__tablename__ = "flights"
id = db.Column(db.Integer, primary_key=True)
origin = db.Column(db.String, nullable=False)
destination = db.Column(db.String, nullable=False)
duration = db.Column(db.Integer, nullable=False)
class Passenger(db.Models):
__tablename__ = "passengers"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
flight_id = db.Column(db.Integer, db.ForeignKey("flights.id",
nullable=False))
output is:
Traceback (most recent call last):
File "create.py", line 4, in
from models import *
File "D:\web\flaskrun\models.py", line 5, in
class Flight(db.Models):
AttributeError: 'SQLAlchemy' object has no attribute 'Models'
As mentioned in the flask-sqlalchemy docs your models need to derive from db.Model without the trailing s
Furthermore it provides a class called Model that is a declarative base which can be used to declare models:
It should be db.Model instead of db.Models.
I got this same error because there was typing mistake I made the s small in string method for datatype like
db.String()--->correct
db.string()--->Incorrect
name=db.Column(db.String(),nullable=False)
Hope this helps someone
Related
I've installed SQLAlchemy by adding it through project settings but am getting this error which i can't seem to figure out:
Traceback (most recent call last):
File "/Users/backup/PycharmProjects/pythonProject/app.py", line 5, in
db=SQLAlchemy(app)
NameError: name 'SQLAlchemy' is not defined
app.py:
from flask import Flask, render_template
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'
db = SQLAlchemy(app)
class Todo(db.model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
completed=db.Column(db.integer, default=0)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
#app.route('/')
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
You've forgot to import sqlalchemy module in the beginning:
from flask_sqlalchemy import SQLAlchemy
I have a simple Python script (models.py) to create a Flask-SQLAlchemy app and a simple sqlalchemy dataclass (reference here) that looks like this:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///test.db"
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = 'user'
user_id: db.Column(db.Integer, primary_key=True)
user_url: db.Column(db.String(2083), unique=True, nullable=False)
username: db.Column(db.String(80), unique=True, nullable=False)
avatar_url: db.Column(db.String(2083), unique=True, nullable=False)
I then wrote an extremely simple pytest script that looks like this, following the example on creating a Flask-SQLAlchemy app from here:
import pytest
from models import User
from models import db
def test_basic():
db.create_all()
u1 = User(1, "http://testuserurl", "charliebrown", "http://avatarurl")
assert u1.user_id == 1
assert u1.user_url == "http://testuserurl"
assert u1.username == "charliebrown"
assert u1.avatar_url == "http://avatarurl"
This test fails immediately on the line "from models import User" with the message:
sqlalchemy.exc.ArgumentError: Mapper mapped class User->user could not
assemble any primary key columns for mapped table 'user'
I don't understand this message (specially given that I do indeed specify the primary_key in User). Any help please?
Try to use = instead of :
Like this:
class User(db.Model):
__tablename__ = 'user'
user_id = db.Column(db.Integer, primary_key=True)
user_url = db.Column(db.String(2083), unique=True, nullable=False)
username = db.Column(db.String(80), unique=True, nullable=False)
avatar_url = db.Column(db.String(2083), unique=True, nullable=False)
'''
import db.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app =Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///posts.db'
class Question(db.model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db,Text, nullable=False)
Date_Posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
def __repr__(self):
return 'Question' + str(self.id)
#app.route('/mainpage' , methods = ['GET'])
def mainpage():
return render_template("main.html")
#app.route('/askdaiwik')
def ask():
return render_template("ask.html" , ask = all_ask)
if __name__ == "__main__":
app.run(debug=True)
'''
If I'm not wrong you are trying to use SQLAlchemy object as db. But you didn't create the object and hence db is undefined.
wrap your app with SQLAlchemy to create the object and assign the variable db to the instance.
db = SQLAlchemy(app)
In db.py where you can store the code db = SQLAlchemy().
Then import it in app.py. Now you can call db.
or just remove APP in db=SQLAlchemy(app)
I'm working on a flask application where I'm trying to isolate my unit tests. I'm using flask-sqlalchemy, and I'm trying to use the create_all and drop_all methods to clean my database after running a test.
However, it appears my create_all and drop_all methods do not actually create/drop the tables as the documentation states. I have my models imported in the application before calling create_all, like most other answers say.
This is the error I'm getting with the code below:
psycopg2.ProgrammingError: relation "tasks" does not exist
Here's my relevant code
/app.py
import os
import configparser
from flask import Flask
from src.router import router
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
app = Flask(__name__)
if not os.path.exists(os.path.join(app.root_path, 'config.ini')):
raise Exception(f'config.ini not found in the {app.root_path}')
config = configparser.ConfigParser()
config.read('config.ini')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = config[os.environ['APP_ENV']]['DATABASE_URI']
app.register_blueprint(router)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
if __name__ == "__main__":
app.run()
/tests/test_router.py
from unittest import TestCase
from flask import Flask
from app import app, db
from src.models import Task
class TestRouter(TestCase):
def setUp(self):
db.create_all()
def tearDown(self):
db.drop_all()
def test_adds_task(self):
task = Task(task_id='task_1', name='my task')
db.session.add(task)
db.session.commit()
I think I was a little quick to post the question, but I hope this might help others come up with other ideas on how to troubleshoot a similar issue.
In my src/models.py file where I keep my models, you must make sure that your models are defined correctly. Since Flask-SQLAlchemy is a wrapper around the SQLAlchemy you must use the data types under the db object.
Essentially, I had my models defined as such:
class Task(db.Model):
__tablename__ = 'tasks'
id = Column(Integer, primary_key=True)
task_id = Column(String)
name = Column(String)
created_at = Column(DateTime, default=datetime.datetime.now)
As you can see, I was inheriting from db.Model instead of the return value of declarative_base(). I also needed to add the db. in front of all the data types, including Column, Integer, String, Float, DateTime, relationship, and ForeignKey.
So, I was able to fix my issue by changing my model to something like:
class Task(db.Model):
__tablename__ = 'tasks'
id = db.Column(db.Integer, primary_key=True)
task_id = db.Column(db.String)
name = db.Column(db.String)
created_at = db.Column(db.DateTime, default=datetime.datetime.now)
See: Documentation on declaring Flask-SQLAlchemy models
i use pycharm 5.0 and python3.5.And i download all the liarbry by the build-in function of pycharm(setting-project-project interpreter-"+").other libraries appear well,but some problems happens to flask-SQLAlchemy.
i import flask-SQLAlchemy successfully.however,pycharm remind me that "unresolved attribute reference 'Column' in class'SQLAlchemy'"."unresolved attribute reference 'relationship' in class 'SQLAlchemy'" and so on.
I have try some ways ,but they didn't work.for example:1.restart 2.remove and redownload 3.refresh the cache.which mention in PyCharm shows unresolved references error for valid code
code:
from flask import Flask, redirect, render_template, session, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from flask_bootstrap import Bootstrap
from flask_wtf import Form
from wtforms import StringField, SubmitField
import os
from wtforms.validators import data_required
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess string'
app.config['SQLALCHEMY_DATABASE_URI'] =\
'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
bootstrap = Bootstrap(app)
db = SQLAlchemy(app)
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
users = db.relationship('User', backref='role', lazy='dynamic')
def __repr__(self):
return '<Role %r>' % self.name
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __repr__(self):
return '<User %r>' % self.username
how can i solve this problem?
The constructor of the flask_sqlalchemy.SQLAlchemy class calls _include_sqlalchemy, which attaches all attributes from sqlalchemy and sqlalchemy.orm to its instances.
This is only done at runtime and not detected by PyCharm's code inspection.
It would require flask_sqlalchemy to use a more standard way of importing those attributes, like from sqlalchemy import *. But this would import the attributes into the flask_sqlalchemy module instead of each instance of SQLAlchemy and thus change the way they're accessed.
I'm not a Python or SQLAlchemy expert and won't judge whether this is good design or not but you could open an issue on https://github.com/pallets/flask-sqlalchemy and discuss it there.
here is what I do.
from flask_sqlalchemy import SQLAlchemy
from typing import Callable
class MySQLAlchemy(SQLAlchemy): # Or you can add the below code on the SQLAlchemy directly if you think to modify the package code is acceptable.
Column: Callable # Use the typing to tell the IDE what the type is.
String: Callable
Integer: Callable
db = MySQLAlchemy(app)
class User(db.Model, UserMixin):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(20)) # The message will not show: Unresolved attribute reference 'Column' for class 'SQLAlchemy'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
def create_test_data():
db.create_all()
test_user = User(name='Frank') # I add __init__, so it will not show you ``Unexpected argument``
db.session.add(test_user)
db.session.commit()
I've ran into the same problem just now.
In short if I just hit Run the code runs with exit code 0 even is PyCharm shows Unresolved attribute reference
but for anyone who might make the same mistake as I did before simply hitting Run:
This is the code that I was writing and it showed 'Unresolved attribute reference 'Column' for class 'SQLAlchemy'' also for eg. 'Unresolved attribute reference 'Integer' for class 'SQLAlchemy' '.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///new-books-collection.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =
False
db = SQLAlchemy(app)
class Books(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(250), unique=True, nullable=False)
author = db.Column(db.String(250), unique=True, nullable=False)
rating = db.Column(db.Float, nullable=False)
db.create_all()
My problem was that I hovered over Column and Integer and clicked Add method Column() to class SQLAlchemy. Also the same with Integer.
From that moment TypeErrors came up for me because it created these empty methods in __init__.py of SQLAlchemy.
To solve this I used pip install flask_sqlalchemy --upgrade and pip install flask_sqlalchemy. And did not Add methods again. It still showed Unresolved attribute reference, but the code ran with exit code 0 and the database was created, with the right data inside.
Hope that helps!
Check the version of flask_sqlalchemy in your pycharm or environment.
i had same problem ,the easiest solution
pip install flask_sqlalchemy --upgrade
100% its gone work.