Reputation: 35
I,m total new to Flask Web development(still learning). I tried to register a new user from the register page of my flask application and then I got this error.
"SQLite DateTime type only accepts Python "
sqlalchemy.exc.StatementError: (builtins.TypeError) SQLite DateTime type only accepts Python datetime and date objects a
s input.
[SQL: INSERT INTO user (username, email, password_hash, about_me, last_seen) VALUES (?, ?, ?, ?, ?)]
[parameters: [{'password_hash': 'pbkdf2:sha256:150000$Wknz8xPs$b1694e1d9b6b8f6a2c171147c37a1f96ff27be9da39ee825cf442f382
0c32313', 'email': '[email protected]', 'username': 'test', 'about_me': None}]]
127.0.0.1 - - [08/Jun/2019 15:07:18] "POST /register HTTP/1.1" 500 -
Here's my models.py
from datetime import datetime
from app import db
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
from hashlib import md5
from app import login
@login.user_loader
def load_user(id):
return User.query.get(int(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)
password_hash = db.Column(db.String(128))
posts = db.relationship('Post', backref='author', lazy='dynamic')
about_me = db.Column(db.String(140))
last_seen = db.Column(db.DateTime, default="datetime.utcnow")
def __repr__(self):
return '<User {}>'.format(self.username)
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
def avatar(self, size):
digest = md5(self.email.lower().encode('utf-8')).hexdigest()
return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format(
digest, size)
And here's my register view function
@app.route('/register', methods=['GET', 'POST'])
def register():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
flash('Congratulations, you are now a registered user!')
return redirect(url_for('login'))
return render_template('register.html', title='Register', form=form)
Upvotes: 1
Views: 7204
Reputation: 13185
You are trying to pass a function to the default
parameter. As shown in the docs this should be a function reference (but not called). In your example, you have provided a string instead.
Change:
last_seen = db.Column(db.DateTime, default="datetime.utcnow")
To:
last_seen = db.Column(db.DateTime, default=datetime.utcnow)
This is why the Mega Tutorial has had you do from datetime import datetime
.
Side note: This error message is actually not correct for SQLite. SQLite does not enforce strict column types, so you can insert strings into integer type columns etc. That's not to say that the error isn't useful, since SQLAlchemy will rely on the column datatype anyway, but it is not strictly enforced by SQLite itself, which might catch you off-guard at a later date.
import sqlite3
with sqlite3.connect(':memory:') as conn:
c = conn.cursor()
# Create a table and try enforce a datetime type
c.execute("""
CREATE TABLE IF NOT EXISTS test(
id PRIMARY KEY,
datetime DATETIME)
""")
conn.commit()
c.execute("""
INSERT INTO test
VALUES (?, ?)
""", (None, '123')) # Insert non-datetime value into datetime col
conn.commit()
c.execute("SELECT * FROM test")
print(c.fetchall()) # Worked just fine
Upvotes: 3