I want to load database value? using sql alchmey.
If I ask using get mehtod '127.0.0.1/api/v1/user/25/'
There is a value in database(id=5, username=jaeyeon, email=jae#naver.com)
I want to show this column.
but it can't. Where can I fix the code?
I don't know how parameter deliver.. Please help me :(
from flask import Flask, url_for, redirect
from flask_sqlalchemy import SQLAlchemy
from flask_restful import reqparse, abort, Api, Resource
app = Flask(__name__)
api = Api(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:12345#localhost/catchat'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
password = db.Column(db.String(120), unique=True)
def __init__(self, username, email, password):
self.username = username
self.email = email
self.password = password
def __repr__(self):
return '<User %r>' % self.username
class user(Resource):
def get(self, id):
args = parser.parse_args()
user_id = db.session.query(User.id == args['id']).filter(id)
print user_id
entry = [dict(id=user.id, username=user.username, email=user.email, password=user.password)]
print entry
return entry, 200
api.add_resource(user,'/api/v1/user/<int:id>')
if __name__ == '__main__':
app.run(debug=True)
You've set up your session a bit differently than I'm used to doing, so I'm not sure whether that makes any difference, but I can see some issues with the query you're making. Try this instead:
user_id = db.session.query(User).filter_by(id = args['id']).one()
Assuming that args['id'] is going to produce the proper value, then this will return the single matching row from User, and you can use dot notation to access the columns. I see you seem to be a bit off when using the dot notation, remember that the values are now stored in user_id so you'd have to access them like this:
email = user_id.email
Related
I am a beginner and I am building my first web application. I will use SendGrid API to send emails to users. I already created an account on SendGrid and imported everything that I need and also already tested sending an email. It is working! Now I am having a hard time trying to figure out how I am going to retrieve data from my database and use SendGrid to send the email. I am using Python and my database is on Model.py (I am using postgresql).
Does anyone have any thoughts to help me?
Code in model.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
"""A user."""
__tablename__ = "users"
user_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
fname = db.Column(db.String)
lname = db.Column(db.String)
email = db.Column(db.String, unique=True)
password = db.Column(db.String)
photo = db.Column(db.String)
letters = db.relationship("Letter", back_populates="user")
favorites = db.relationship("Letter", secondary="favorites", back_populates="user")
def __repr__(self):
"""Show info about user."""
return f'<User user_id={self.user_id} email={self.email}>'
class Letter(db.Model):
"""A letter."""
__tablename__ = "letters"
letter_id = db.Column(db.Integer, autoincrement=True, primary_key=True)
letter_title = db.Column(db.String)
letter_body = db.Column(db.String)
creation_date = db.Column(db.Date)
delivery_date = db.Column(db.Date)
likes = db.Column(db.Integer)
read = db.Column(db.Boolean)
publish = db.Column(db.Boolean)
user_id = db.Column(db.Integer, db.ForeignKey("users.user_id"))
# create a relationship
user = db.relationship("User", back_populates="letters")
def __repr__(self):
"""Show info about letter."""
return f'<Letter letter_id={self.letter_id} letter_title={self.letter_title}>'
"""This is my server.py (this is just one of my routes)"""
from flask import (Flask, render_template, request, flash,
session, redirect)
import random
from model import connect_to_db, db
import crud
from jinja2 import StrictUndefined
import os
import cloudinary.uploader
CLOUDINARY_KEY = os.environ['CLOUDINARY_KEY']
CLOUDINARY_SECRET = os.environ['CLOUDINARY_SECRET']
CLOUD_NAME = "dnw3idclo"
app = Flask(__name__)
app.secret_key = "dev"
app.jinja_env.undefined = StrictUndefined
#app.route("/registration", methods=["POST"])
def create_user():
"""Create a user account."""
fname = request.form.get("fname")
lname = request.form.get("lname")
email = request.form.get("email")
password = request.form.get("password")
photo = request.files['my-file']
response= send_user_profile_pic(photo)
if 'secure_url' in response:
photo_url = response['secure_url']
else:
photo_url = ""
user = crud.get_user_by_email(email)
if user:
flash("You cannot create an account with that email. Please try again.")
else:
user = crud.create_user(fname=fname, lname=lname, email=email, password=password, photo=photo_url)
db.session.add(user)
db.session.commit()
flash("Account created succesfully! Please log in.")
"""Also use crud functions to query data from my data base:"""
from model import db, User, Letter, Favorite, connect_to_db
def create_user(fname, lname, email, password, photo):
"""Create user's account."""
user_account = User(fname=fname, lname=lname, email=email, password=password, photo=photo)
return user_account
def get_user_by_email(email):
"""Return a user by email."""
return User.query.filter(User.email == email).first()
def get_user_by_id(user_id):
return User.query.get(user_id)
def create_letter_for_user(letter_title, letter_body, creation_date, delivery_date, likes, read, publish, user_id):
"""Create letter for users."""
letter = Letter(
letter_title=letter_title,
letter_body=letter_body,
creation_date=creation_date,
delivery_date=delivery_date,
likes=likes,
read=read,
publish=publish,
user_id=user_id)
return letter
"""And finally is my file for SendGrid:"""
import sendgrid
import os
from sendgrid.helpers.mail import Mail, Email, To, Content
from model import connect_to_db, db
import crud
from flask import (Flask, render_template, redirect, session,
request,)
from jinja2 import StrictUndefined
app = Flask(__name__)
app.secret_key = "dev"
app.jinja_env.undefined = StrictUndefined
# import model, crud, server, flask
sg = sendgrid.SendGridAPIClient(api_key=os.environ.get('SENDGRID_API_KEY'))
from_email = Email("sender.test#gmail.com") # changed to my verified sender
to_email = To("receiver.test#gmail.com") # the recipient that I want to send the email
subject = "Letter to Your Future Self"
content = Content("text/plain", "Test, test, test and more test")
mail = Mail(from_email, to_email, subject, content)
# Get a JSON-ready representation of the Mail object
mail_json = mail.get()
# Send an HTTP POST request to /mail/send
response = sg.client.mail.send.post(request_body=mail_json)
print(response.status_code)
print(response.headers)
Thank you!
I am following the tutorial at https://www.digitalocean.com/community/tutorials/how-to-add-authentication-to-your-app-with-flask-login for adding register/login features to a flask app, which uses Flask-Login with an SQLite database (using flask_sqlalchemy). As such, it has code like the following for initializing the SQLite database (from init.py):
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config['SECRET_KEY'] = '9OLWxND4o83j4K4iuopO'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///db.sqlite'
db.init_app(app)
And then creates a User class (as is required by Flask-Login) like this:
from flask_login import UserMixin
from . import db
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True) # primary keys are required by SQLAlchemy
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(100))
name = db.Column(db.String(1000))
However, I want to store user information in a dynamodb table, not a SQLite table. How then should I write the User class? I want each User to have an email, password and name property like in this tutorial (along with other properties/methods required at https://flask-login.readthedocs.io/en/latest/#your-user-class as is handled by UserMixin), but am unsure how to write the class when using dynamodb.
I wrote the User class simply as follows:
class User(UserMixin):
def __init__(self, id, email, name, password):
self.id = id
self.email = email
self.name = name
self.password = password
I used the User class from ZhouW and you will also need a custom user_loader. This here should work:
class User(UserMixin):
def __init__(self, id, email, password):
self.id = id
self.email = email
self.password = password
#login_manager.user_loader
def loader(user_id):
response = table.query(
KeyConditionExpression=Key('id').eq(user_id))
if response["Count"] == 0:
return
user = User(id=response['Items'][0]["id"], email=response['Items'][0]["email"], password=response['Items'][0]["password"])
return user
Will need a table first, connect something like this:
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('users')
from boto3.dynamodb.conditions import Key
This question already has answers here:
How Can I Automatically Populate SQLAlchemy Database Fields? (Flask-SQLAlchemy)
(2 answers)
Closed 4 years ago.
I am new to SQLAlchemy and have been unable to set the DateTime for created. I have tried using the "default" option found in many examples. I have also tried setting it manually (I have it commented out). Neither have worked so far. Any help would be appreciated.
models.py
import datetime
from flask.ext.sqlalchemy import SQLAlchemy
from werkzeug import generate_password_hash, check_password_hash
db = SQLAlchemy()
class User(db.Model):
__tablename__ = 'users'
uid = db.Column(db.Integer, primary_key=True)
firstname = db.Column(db.String(40))
lastname = db.Column(db.String(40))
email = db.Column(db.String(120), unique=True)
created = db.Column(db.DateTime, default=datetime.datetime.utcnow())
confirmed = db.Column(db.DateTime, nullable=True)
pwdhash = db.Column(db.String(100))
def __init__(self, firstname, lastname, email, password):
self.firstname = firstname.title()
self.lastname = lastname.title()
self.email = email.lower()
self.set_password(password)
#self.created = datetime.datetime.utcnow()
self.confirmed = None
def set_password(self, password):
self.pwdhash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.pwdhash, password)
routes.py
from tasks import app
from datetime import datetime
from flask import render_template, request, flash, session, url_for, redirect
from forms import ContactForm, SignupForm, SigninForm
from flask.ext.mail import Message, Mail
from models import db, User, Tags, Tasks
#app.route('/signup', methods=['GET', 'POST'])
def signup():
form = SignupForm()
if 'email' in session:
return redirect(url_for('profile'))
if request.method == 'POST':
if form.validate() == False:
return render_template('signup.html', form=form)
else:
newuser = User(form.firstname.data, form.lastname.data, form.email.data, form.password.data)
db.session.add(newuser)
db.session.commit()
session['email'] = newuser.email
return redirect(url_for('profile'))
elif request.method == 'GET':
return render_template('signup.html', form=form)
The problem with your default is that you're calling datetime.utcnow immediately there, and the value returned (at the time of class definition) is always used as default. You need to pass the callable itself like following:
# Note the lack of parenthesis after datetime.utcnow
created = db.Column(db.DateTime, default=datetime.datetime.utcnow)
This way SQLAlchemy will call datetime.utcnow itself upon row insert.
Ame getting this error of TypeError: init() takes exactly 1 argument (5 given)...where have i gone wrong?? any help i will appreciate ,thanks
thats my db_create.py file
from app import db
from models import post
db.create_all()
db.session.add(post("Good", "i\m good","yes","hae"))
db.session.add(post("Good", "hahaha"))
db.session.add(post("Good", "you"))
db.session.add(post("Good", "hahaha"))
my model.py file is
from app import db
class post(db.Model):
# table name
__tablename__ = "signup"
#columns names
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, nullable=False)
email= db.Column(db.String, nullable=False)
password = db.Column(db.String, nullable=False)
confirm= db.Column(db.String, nullable=False)
def __init__(self, username, email, password, confirm):
self.username = username
self.email = email
self.pasword = password
self.confirm = confirm
def __repr__(self,*args, **kwargs):
return '<username {}'.format(self.username), 'email{}'.format(self.email),'password{}'.format(self.password)
this is my init
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.secret_key = "my previous"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///signup.db'
db = SQLAlchemy(app)
from app import views
You don't need the __init__ method in your post model. Just use the __init__ method inherited from db.Model and you should be fine.
But then I believe you'd need to modify your db_create.py a bit:
For example:
db.session.add(post(username="User", email="user#email.com", password="password", confirm="Yes"))
Also you need to remember to commit your changes:
db.session.commit()
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return '<User %r>' % self.username
This code I have found in SQLAlchemy documentation. db=SQLAlchemy(app) It means that db is a object. class User(db.Model) by looking at the line it looks like that db is a module name.
what basically db is?can someone explain me.
https://developers.google.com/appengine/docs/python/datastore/modelclass
I have read this but not able to understand.
The db = SQLAlchemy(app) is the way to set the db variable with the correct app context, is basically to register the application on db instance, we use this to associate the application bound to the current context