Trying to create a databases using the flask-SQLAlchemy module. When I insert this code into the command line "from sqlalchemy import db".
I get this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\andre\AppData\Local\Programs\Python\Python38\sqlalchemy.py", line 1
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)] on win32
^
SyntaxError: invalid syntax.
Here is my code:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']= 'sqlite:///site.db'
db = SQLAlchemy(app)
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(120), unique=True, nullable=False)
image_file=
db.Column(db.String(20),nullable=False,default='default.jpg')
password = db.Column(db.String(60), nullabale=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)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
Could someone please help me? I've been stuck on this quite some time. I've installed flask-SQLAlchemy and updated my pip. Don't know what else to do really.
You had some typos in the code and not sure regarding that image_file= line so removed that line for now, follow the below code it would provide u with db
edited: didnt saw that image file one line updated it can you check
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
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(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)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
db.create_all() # this create the site.db
Related
from yff import db, login_manager, app
from flask_login import UserMixin
import datetime
import jwt
#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)
password = db.Column(db.String(120), unique=False, nullable=False)
email = db.Column(db.String(50), unique=False, nullable=False)
profile_pic = db.Column(db.String(30), unique=False, default="default.jpg")
is_moderator = db.Column(db.Boolean, default=False)
posts = db.relationship('Posts', backref='author', lazy=True)
likes = db.relationship('Likes', backref='user', passive_deletes=True)
comments = db.relationship('Comment', backref='user', passive_deletes=True)
def get_reset_token(self):
encoded = jwt.encode({'user_id':self.id, "exp":datetime.datetime.now() + datetime.timedelta(hours = 0.5)}, app.config['SECRET_KEY'], algorithm='HS256')
return encoded
#staticmethod
def verify_secret_token(token):
try:
decoded = jwt.decode(token, options={"verify_signature": False})
user_id = decoded['user_id']
except:
return None
return User.query.get(user_id)
def __repr__(self):
return f'{self.username}, {self.email}'
class Image(db.Model):
id = db.Column(db.Integer, primary_key=True)
title=db.Column(db.String(120), nullable=False)
date_created = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now(tz=datetime.timezone.utc))
img_location = db.Column(db.String(600), nullable=False)
mimetype = db.Column(db.String(10))
post_name = db.Column(db.String(150),nullable=False, unique=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
manga_name = db.Column(db.String(100), unique=False, nullable=False)
class Posts(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
post_id = db.Column(db.Integer, db.ForeignKey('image.id', ondelete="CASCADE"), nullable=False)
likes = db.Column(db.Integer, db.ForeignKey('likes.id', ondelete='CASCADE'))
date_created = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now(tz=datetime.timezone.utc))
comments = db.relationship('Comment', backref='Posts', passive_deletes=True)
class Likes(db.Model):
id = db.Column(db.Integer, primary_key=True)
author = db.Column(db.Integer, db.ForeignKey('user.id', ondelete="CASCADE"), nullable=False)
post_id = db.Column(db.Integer, db.ForeignKey('image.id', ondelete="CASCADE"), nullable=False)
liked_post = db.relationship('Posts', backref='post')
class Comment(db.Model): #import it in the __init__ file
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(1000), nullable=False)
date_created = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now(tz=datetime.timezone.utc))
author = db.Column(db.Integer, db.ForeignKey('user.id', ondelete="CASCADE"), nullable=False)
post_id = db.Column(db.Integer, db.ForeignKey('image.id', ondelete="CASCADE"), nullable=False)
The following is the entire error:
sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'mapped class Posts->posts'. Original exception was: Could not determine join condition between parent/child tables on relationship Posts.comments - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
I am getting this error in the pythonanywhere error log. I tried changing the positions of the backref statement but I that did not help. (I am new to web dev and I still haven't figured out how backref works)
I know how foreign keys work in SQL but I am still not experienced at OOP and SQLAlchemy, so please help me out.
I'm trying to create to blog but I'm having issues creating database using sqlite as my database engine in which I created classes to define each table schema using an ORM with flask-sqlalchemy and also another thing I noticed was it created an empty blog.db file. I cant solve the issue im having right now. As of now this is my resort for help before using Firebase.
models.py
from blogent import db
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
first_name = db.Column(db.String(50), nullable=False)
last_name = db.Column(db.String(50), nullable=False)
email = db.column(db.String(50), unique=True, nullable=False)
image = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(50), nullable=False)
post = db.relationship('Post', backref='author', lazy=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow())
updated_at = db.Column(db.DateTime, default=datetime.utcnow())
def __repr__(self):
return f"User('{self.email}', '{self.image}', '{self.created_at}')"
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
post_name = db.Column(db.String(30), nullable=False)
post_title = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
comments = db.relationship('Comments', backref='posts', lazy=True)
user = db.relationship('User', backref='users', lazy=True)
created_at = db.Column(db.DateTime, default=datetime.utcnow())
updated_at = db.Column(db.DateTime, default=datetime.utcnow())
def __repr__(self):
return f"Post('{self.post_name}', '{self.post_title}', '{self.created_at}')"
class Comments(db.Model):
id = db.Column(db.Integer, primary_key=True)
post_id = db.Column(db.Integer, db.ForeignKey('post.id'))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
content = db.Column(db.Text, nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow())
updated_at = db.Column(db.DateTime, default=datetime.utcnow())
def __repr__(self):
return f"Comments('{self.content}', '{self.created_at}')"
init.py
from flask_cors import CORS
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///blog.db"
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_ECHO'] = True
app.config['SECRET_KEY'] = '48ea69eb3539fbe7e069deee6c74d46d'
db = SQLAlchemy(app)
#app.before_first_request
def create_tables():
db.create_all()
from blogent import routes
I am creating a server application that will utilize a remote database created by a Flask GUI. To keep things simple (and since it's primarily threaded calculations), I want to build my server application without utilizing a Flask framework. I will have a redis message server to keep the two processes in sync.
My challenge is that I want to use persistent storage wherever possible. So as part of this, my server application will need to import the Flask-SQLAlchemy database files to retrieve the parameters. The difficulty I am having is to write the import statement that will pull the SQLAlchemy files into pandas. Here is what I have so far:
config.py
import os
class Config:
SQLALCHEMY_DATABASE_URI_REMOTE = os.environ.get('RDQ_LOGIN') # remote docker database
SQLALCHEMY_DATABASE_URI_LOCAL = os.environ.get('RDU_LOGIN') # local file database
REDIS_IP = os.environ.get('REDIS_IP')
REDIS_PASSWORD = os.environ.get('REDIS_PASSWORD')
init.py
from src_code.config import Config
import redis
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy import orm
from sqlalchemy.ext.declarative import declarative_base
import sqlalchemy as sa
engine_remote = create_engine(Config.SQLALCHEMY_DATABASE_URI_REMOTE, echo=True)
Base_remote = declarative_base()
Base_remote.metadata.create_all(engine_remote)
Session_remote = sessionmaker(bind=engine_remote)
Session_remote.configure(bind=engine_remote)
session_remote = Session_remote()
engine_local = create_engine(Config.SQLALCHEMY_DATABASE_URI_LOCAL, echo=True)
Base_local = declarative_base()
Base_local.metadata.create_all(engine_local)
Session_local = sessionmaker(bind=engine_local)
Session_local.configure(bind=engine_local)
session_local = Session_local()
redisChannel = redis.StrictRedis(host=Config.REDIS_IP, port=6379, password=Config.REDIS_PASSWORD,
decode_responses=True)
main.py
import pandas as pd
from src_code import session_local, session_remote
def start():
table_df = pd.read_sql(
'SELECT * from game',
con=session_remote
)
print(table_df)
if __name__ == "__main__":
start()
Unfortunately I am getting an error:
AttributeError: 'Session' object has no attribute 'cursor'
I don't need to be able to write back to the table (so read-only is sufficient). So I am using a simple example that would give me the ability to extract what I need from the panda (I am more confident to use pandas than SQL).
I do have the model statements that I could replicate in the server code if this would somehow facilitate the process:
from datetime import datetime
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from flask import current_app
from src_code 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)
agent = db.Column(db.Integer, unique=False, nullable=False)
image_file = db.Column(db.String(20), unique=False, nullable=False,default='default.jpg')
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
games_started = db.relationship('Game', backref='captained', lazy=True)
games_played = db.relationship('Player', backref='games', lazy=True)
def get_reset_token(self, expires_sec=1800):
s = Serializer(current_app.config['SECRET_KEY'], expires_sec)
return s.dumps({'user_id': self.id}).decode('utf-8')
#staticmethod
def verify_reset_token(token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
user_id = s.loads(token)['user_id']
except:
return None
return User.query.get(user_id)
def __repr__(self):
return f"User('{self.username}', '{self.email}', '{self.agent}', '{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)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
class Game(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(60), nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
company_count = db.Column(db.Integer, nullable=False)
starting_year = db.Column(db.Integer, nullable=False)
time_limit = db.Column(db.Integer, nullable=False)
agent_decisions_visible = db.Column(db.Boolean, nullable=False)
client_count = db.Column(db.Integer, nullable=False)
pre_game_yrs = db.Column(db.Integer, nullable=False)
time_index = db.Column(db.Integer, nullable=False)
game_active = db.Column(db.Boolean, nullable=False)
player_capt = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
games_msgs = db.relationship('Messages', backref='messages', lazy=True)
def __repr__(self):
return f"Game('{self.title}', '{self.date_posted}')"
class GameRequests(db.Model):
id = db.Column(db.Integer, primary_key=True)
date_requested = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
game_id = db.Column(db.Integer, db.ForeignKey('game.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"GameRequest('{self.game_id}', '{self.user_id}', '{self.date_requested}'"
class GameDecisions(db.Model):
id = db.Column(db.Integer, primary_key=True)
date_requested = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
game_id = db.Column(db.Integer, db.ForeignKey('game.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
time_index = db.Column(db.Integer, nullable=False)
def __repr__(self):
return f"GameDecisions('{self.game_id}', '{self.user_id}', '{self.time_index}'"
class Player(db.Model):
id = db.Column(db.Integer, primary_key=True)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
game_id = db.Column(db.Integer, db.ForeignKey('game.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
def __repr__(self):
return f"Player('{self.game_id}', '{self.user_id}', '{self.date_posted}'"
class Messages(db.Model):
id = db.Column(db.Integer, primary_key=True)
date_posted = db.Column(db.DateTime, nullable=False,default=datetime.utcnow)
type = db.Column(db.String(10), nullable=False)
msg_from = db.Column(db.String(20), nullable=False)
msg_to = db.Column(db.String(20), nullable=False)
message = db.Column(db.String(60), nullable=False)
game_id = db.Column(db.Integer, db.ForeignKey('game.id'), nullable=False)
def __repr__(self):
return f"Messages('{self.game_id}', '{self.id}', '{self.message}', '{self.date_posted}')"
Thanks for any help you can offer!
Similar to your conclusion, here's how I read databases into pandas:
# Create your query.
# This can be as complex or simple as you'd like
query = session_remote.query(Game)
df = pd.read_sql(query.statement, session_remote.bind)
The key difference here is the utilization of the ORM to perform (or rather, write) the query itself.
Masking SQL behind an ORM has many advantages -- I strongly recommend against utilizing raw SQL in production backends.
It seems I was closer than I realized. The following code did what I needed:
SQLAlchemy ORM conversion to pandas DataFrame
table_df = pd.read_sql(
'SELECT * from game',
session_remote.bind
)
so I just got done following python YouTuber Corey Schafers tutorial on flask-sqlalchemy. I'm having problems modifying the DB we created. I'm trying to make a relation to my Comment table and User table. When a user posts a comment I want to store the user's name. So far I can't seem to link a user's comment on a post to the name of the author of the comment. This is the code that's relevant.
from datetime import datetime
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from smushd_site import db, login_manager
from flask_login import UserMixin
from flask import current_app
#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)
#comments_name = db.relationship('Comment', backref='author_comment', lazy=True)
def get_reset_token(self, expires_sec=1800):
s = Serializer(current_app.config['SECRET_KEY'], expires_sec)
return s.dumps({'user_id': self.id}).decode('utf-8')
#staticmethod
def verify_reset_token(token):
s = Serializer(current_app.config['SECRET_KEY'])
try:
user_id = s.loads(token)['user_id']
except:
return None
return User.query.get(user_id)
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)
comments = db.relationship('Comment', backref='author', lazy=True)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
class Comment(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(100), nullable=False)
name = db.Column(db.String(100), nullable=False,default="stalin")
timestamp = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
#poster_id = db.Column(db.String(100), db.ForeignKey('poster.id'), nullable=False)
post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)
#comment_name = db.Column(db.String(100), nullable=False)
#username = db.Column(db.String(100), db.ForeignKey('user.id'), nullable=False)
#comment_name = db.relationship('User', backref='author', lazy=True)
def __repr__(self):
return f"Comment('{self.body}', '{self.timestamp}')"
These are the link to the repo with the code and youtube series:
https://github.com/CoreyMSchafer/code_snippets/blob/master/Python/Flask_Blog/12-Error-Pages/flaskblog/models.py
https://www.youtube.com/watch?v=cYWiDiIUxQc&list=PL-osiE80TeTs4UjLw5MM6OjgkjFeUxCYH&index=4
Here is the code I wrote; it might help you. Feedback is just an example - you can do the same thing with Comment.
class User(db.Model, UserMixin):
__bind_key__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(25), unique=True, nullable=False)
email = db.Column(db.String(125), unique=True, nullable=False)
image_file = db.Column(db.String(20), nullable=False, default='default.jpg')
password = db.Column(db.String(65), nullable=False)
about = db.Column(db.String(100), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
feedbacks = db.relationship('Feedback', backref='author', lazy=True)
create_account = db.Column(db.DateTime, nullable=False, default=datetime.now)
badges = db.Column(db.DateTime, nullable=False, default=datetime.now)
class Feedback(db.Model):
__bind_key__ = 'feedback'
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
date_posted = db.Column(db.DateTime, nullable=False, default=datetime.now)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
run.py file:
from flaskblog import app, db
if __name__ == '__main__':
db.create_all()
app.run(debug=True)
models.py file:
from flaskblog import db
from datetime import datetime
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
img_file = db.Column(db.String(20), nullable=False, default='default.jpeg')
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.img_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)
def __repr__(self):
return f"User { self.title }, { self.date_posted })"
init.py file:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hard to guess'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
db = SQLAlchemy(app)
bcrypt = Bcrypt(app)
from flaskblog import routes
I have tried creating the table using the terminal before running the app using db.create_all() but it still didn't work.
The following error is thrown:
SQLAlchemy.exc.OperationalError : (sqlite3.OperationalError) no such table: user
If anyone could solve this problem, I would really appreciate it.
Thanks.
#from flaskblog import db <- this import is wrong!
from my_project_name import db # the instancfe of SQLAlchemy that you use in your app
from datetime import datetime
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
img_file = db.Column(db.String(20), nullable=False, default='default.jpeg')
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.img_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)
def __repr__(self):
return f"User { self.title }, { self.date_posted })"