I have a Python webapp that is connected to SQL Server database using SQLalchemy migration.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
import urllib
SQLALCHEMY_TRACK_MODIFICATIONS = False
app = Flask(__name__)
app.config['SECRET_KEY'] = '*******************'
params = urllib.parse.quote_plus('DRIVER={SQL Server};SERVER=SOMESERVER;DATABASE=PD;Trusted_Connection=yes;')
app.config['SQLALCHEMY_DATABASE_URI'] = "mssql+pyodbc:///?odbc_connect=%s" % params
db = SQLAlchemy(app)
now the database has a few tables with some values and I have a registration page and a login page that should use that.
but I only know that I can use a model.py file that models the table so that I can use them like this :
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}')"
When I ran the files, the webapp launched normally, but when I entered a form (login or register) I got this error which, I presume, indicates that the table "User" was not found in the database.
sqlalchemy.exc.InterfaceError: (pyodbc.InterfaceError) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
(Background on this error at: https://sqlalche.me/e/14/rvf5)
So should I just change the class name from User to the table name I have in the database, and then name all the fields using the names I have in DB as well? Or is there some other way to just call the table I have in DB and let it fill the "User" class (metaphorically) so that when User is imported, its my DB table that is used?
class User(db.Model, UserMixin):
__table__ = Table('table_name_here')
# rest of your definition
Should sort you.
EDIT: the URL should be something like:
app.config['SQLALCHEMY_DATABASE_URI'] = "mssql+pyodbc://daneil#server/database?driver=ODBC+Driver+17+for+SQL+Serve"
Related
from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql://root:#localhost/digifit"
db = SQLAlchemy(app)
'''class is the table created in the database'''
class Details(db.Model):
sno = db.Column(db.Integer(), primary_key=True)
username = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(8), unique=True, nullable=False)
#app.route("/login",methods=["GET","POST"])
def login():
if request.method=='POST':
'''add entry to the database'''
username=request.form.get('username')
Password=request.form.get('password')
entry = Details(username=username,password=Password)
db.session.add(entry)
db.session.commit()
return render_template("login.html")
this is the code for the program . I am using flask sql alchemy.
The error I am getting on submiting information on login page created is :
1045, "Access denied for user 'root'#'localhost' (using password: NO)")
(Background on this error at: https://sqlalche.me/e/14/e3q8
I'm currently trying my hand at Flask-SQLAlchemy and I'm running into the following problem when it comes to running the commit() method:
First, here is my User class:
from flask_login import LoginManager, UserMixin
from flask_sqlalchemy import Model, SQLAlchemy
from app import db
class User(db.Model, UserMixin):
def __init__(self, id, name, password, active):
self.id = id
self.name = name
self.password = password
self.active = active
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False, unique=True)
password = db.Column(db.String, nullable=False)
active = db.Column(db.Boolean, nullable=False, default=True)
#property
def is_active(self):
return self.active
Now my main app:
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.sqlite'
app.secret_key = b'test'
db = SQLAlchemy(app)
from user import User
db.create_all()
db.session.commit() # This commit works fine!
admin = User(1, 'admin', 'admin', True)
db.session.add(admin)
db.session.commit() # <------ Value Error at this position
print(User.query.all())
And I get the following Error message when I try to run my code:
in flask_sqlalchemy\__init__.py
before_models_committed.send(session.main, changes=list(d.values()))
AttributeError: 'SignallingSession' object has no attribute 'main'
I am using Pycharm and the version of flask_sqlalchemy is 2.5.1
Am I using the module wrong?
Thank you for every helpfull comment!
Kind regards,
Bagheera
Now I don't know if this really counts as a solution, but I tried lowering the version of the flask_sqlalchemy module.
After this didn't work either, because now other error messages appeared, I set the version back to the highest.
After that it worked in a mysterious way. But maybe someone has an explanation for this or experienced something similar.
I just created a Flask application. I am trying to do some database operations. My init class of the app is
import os
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def __get_app() -> Flask:
return Flask(__name__)
def create_app() -> Flask:
app = __get_app()
db.init_app(app)
with app.app_context():
from .routes import api
app.register_blueprint(api)
db.create_all()
db.session.commit()
print("FLASK APP")
return app
and one of the models is
"""Data models."""
from app import db
import json
class User(db.Model):
"""Data model for user accounts."""
__tablename__ = 'flasksqlalchemy-tutorial-users'
id = db.Column(
db.Integer,
primary_key=True,
autoincrement=True
)
username = db.Column(
db.String(64),
index=False,
unique=True,
nullable=False
)
email = db.Column(
db.String(80),
index=True,
unique=True,
nullable=False
)
website = db.Column(
db.String(120),
index=False,
unique=False,
nullable=False
)
password = db.Column(
db.String(20),
index=False,
unique=False,
nullable=False
)
I'm able to create a database and the required tables using the above. The issue that I'm facing is how to save the database and table. I need some guidance on that.
I want to save the database on my local machine.
Update: Further context
I initially don't have a database. After the db.create_all(), I can query to the db and all the relevant tables are created. I want to save that db on the machine hosting the app. I cannot find the db anywhere too and it disappears as soon as I stop the application. Basically, persistence is not maintained between sessions
I'm using SQLAlchemy ORM framework from a Flask project. I wanted to add another column to one of my models. After I did, I used db.session.drop_all() to drop all current entries in the database, and then I tried recreating a new instance with the new field.
Whenever I tried I get this error
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no
such table: user
[SQL: SELECT user.id AS user_id, user.username AS user_username, user.email AS user_email, user.password AS user_password, user.image_file AS user_image_file
FROM user]
I think I might need to reconstruct the database in some way, but I'm not sure how. I looked into the documentation, but could not find anything useful.
__init__.py
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
models.py
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
email = db.Column(db.String(40), unique=True, nullable=False) #newly added field
password = db.Column(db.String(60), nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
messages = db.relationship('Message', backref='user', lazy=True)
When you used db.drop_all() you dropped all tables so now you can't insert data because there is no table. You need create the table again with db.create_all() as #SuperShoot mentioned.
You should use something for migrations like alembic or flask-sqlalchemy.
This way you could add new column to your ORM. Run flask db migrate -m 'new column', this will detect changes. Then run flask db upgrade head to apply those changes to your database.
I am following this tutorial https://www.youtube.com/watch?v=kuyrL6krkwA. I have modified the db, table, and columns names for my app. Everything else is identical to tutorial. The error occurs (10 mins into tutorial) where he enters python shell and runs the following commands:
from models import User # my app uses 'User' not 'BlogPost'
users = User.query.all()
The Python Shell Script returns error message below:
sqlalchemy.exc.OperationalError: (OperationalError) no such
column:users.id u'SELECT users.id AS users_id, users.name AS
users_name, users.zipcode AS users_zipcode, users.inter1 AS
users_inter1, users.inter2 AS users_inter2, users.inter3 AS
users_inter3 \nFROM users' ()
The three files I am using are (App.py, models.py, db_create.py)
App.py
from flask import Flask, render_template, request
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mfiyzc.db'
db = SQLAlchemy(app)
if __name__ == "__main__":
app.run(debug = True)
models.py
from app import db
class User(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
zipcode = db.Column(db.Integer, nullable=False)
inter1 = db.Column(db.String, nullable=False)
inter2 = db.Column(db.String, nullable=False)
inter3 = db.Column(db.String, nullable=False)
def __init__(self, name, zipcode, inter1, inter2, inter3):
self.name = name
self.zipcode = zipcode
self.inter1 = inter1
self.inter2 = inter2
self.inter3 = inter3
def __repr__(self):
return '<title {}'.format(self.title)
db_create.py
from app import db
from models import User
db.create_all()
db.session.add(User("Jane Parker", 11104, "ice skating", "dancing", "reading"))
db.session.add(User("Bob Smith", 11104, "boxing", "cars", "beers"))
db.session.commit()
You need to run db_create.py ie :
python db_create.py
or
from models import User
db.create_all()
You are trying to query the table before it has been created.
I had the wrong field name (since I copied from the tutorial)
incorrect:
def __repr__(self):
return '<title {}'.format(self.title)
correct:
def __repr__(self):
return '<name {}'.format(self.name)