TypeError:“ OperationalError”类型的对象不可JSON序列化

时间:2018-10-23 16:30:01

标签: python json flask web-applications

我正在使用Python和Flask在一个简单的网页上工作,并遇到此错误。我遇到了障碍,似乎无法弄清楚代码出了什么问题。

尝试登录时发生错误。所有其他功能均按预期工作。一旦按下登录按钮,错误就会弹出。

错误:

127.0.0.1 - - [23/Oct/2018 17:14:46] "POST /login HTTP/1.1" 500 -

Traceback (most recent call last):
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\_compat.py", line 35, in reraise
    raise value
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 1816, in full_dispatch_request
    return self.finalize_request(rv)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 1833, in finalize_request
    response = self.process_response(response)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py", line 2114, in process_response
    self.session_interface.save_session(self, ctx.session, response)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\sessions.py", line 375, in save_session
    val = self.get_signing_serializer(app).dumps(dict(session))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py", line 114, in dumps
    payload = want_bytes(self.dump_payload(obj))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\url_safe.py", line 42, in dump_payload
    json = super(URLSafeSerializerMixin, self).dump_payload(obj)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py", line 99, in dump_payload
    return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\tag.py", line 296, in dumps
    return dumps(self.tag(value), separators=(',', ':'))
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py", line 179, in dumps
    rv = _json.dumps(obj, **kwargs)
File "D:\Programe\Anaconda\lib\json\__init__.py", line 238, in dumps
    **kw).encode(obj)
File "D:\Programe\Anaconda\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
File "D:\Programe\Anaconda\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py", line 81, in default
    return _json.JSONEncoder.default(self, o)
File "D:\Programe\Anaconda\lib\json\encoder.py", line 180, in default
    o.__class__.__name__)
TypeError: Object of type 'OperationalError' is not JSON serializable

浏览器错误:

File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2309,in __call__


def __call__(self, environ, start_response):
    """The WSGI server calls the Flask application object as the
    WSGI application. This calls :meth:`wsgi_app` which can be
    wrapped to applying middleware."""
    return self.wsgi_app(environ, start_response)

def __repr__(self):
    return '<%s %r>' % (
        self.__class__.__name__,
        self.name,



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2295,in wsgi_app

        try:
            ctx.push()
            response = self.full_dispatch_request()
        except Exception as e:
            error = e
            response = self.handle_exception(e)
        except:
            error = sys.exc_info()[1]
            raise
        return response(environ, start_response)
    finally:



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 1741,in handle_exception

        # if we want to repropagate the exception, we can attempt to
        # raise it with the whole traceback in case we can do that
        # (the function was actually called from the except part)
        # otherwise, we just raise the error again
        if exc_value is e:
            reraise(exc_type, exc_value, tb)
        else:
            raise e

    self.log_exception((exc_type, exc_value, tb))
    if handler is None:



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\_compat.py",line 35,in reraise

from io import StringIO

def reraise(tp, value, tb=None):
    if value.__traceback__ is not tb:
        raise value.with_traceback(tb)
    raise value

implements_to_string = _identity

else:
text_type = unicode



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2292,in wsgi_app

    ctx = self.request_context(environ)
    error = None
    try:
        try:
            ctx.push()
            response = self.full_dispatch_request()
        except Exception as e:
            error = e
            response = self.handle_exception(e)
        except:
            error = sys.exc_info()[1]



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 1816,in full_dispatch_request

        rv = self.preprocess_request()
        if rv is None:
            rv = self.dispatch_request()
    except Exception as e:
        rv = self.handle_user_exception(e)
    return self.finalize_request(rv)

def finalize_request(self, rv, from_error_handler=False):
    """Given the return value from a view function this finalizes
    the request by converting it into a response and invoking the
    postprocessing functions.  This is invoked for both normal



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 1833,in finalize_request


    :internal:
    """
    response = self.make_response(rv)
    try:
        response = self.process_response(response)
        request_finished.send(self, response=response)
    except Exception:
        if not from_error_handler:
            raise
        self.logger.exception('Request finalizing failed with an '



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\app.py",line 2114,in process_response

    if None in self.after_request_funcs:
        funcs = chain(funcs, reversed(self.after_request_funcs[None]))
    for handler in funcs:
        response = handler(response)
    if not self.session_interface.is_null_session(ctx.session):
        self.session_interface.save_session(self, ctx.session, response)
    return response

def do_teardown_request(self, exc=_sentinel):
    """Called after the request is dispatched and the response is
    returned, right before the request context is popped.



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\sessions.py",line 375,in save_session


    httponly = self.get_cookie_httponly(app)
    secure = self.get_cookie_secure(app)
    samesite = self.get_cookie_samesite(app)
    expires = self.get_expiration_time(app, session)
    val = self.get_signing_serializer(app).dumps(dict(session))
    response.set_cookie(
        app.session_cookie_name,
        val,
        expires=expires,
        httponly=httponly,



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py",line 114,in dumps

def dumps(self, obj, salt=None):
    """Returns a signed string serialized with the internal
    serializer. The return value can be either a byte or unicode
    string depending on the format of the internal serializer.
    """
    payload = want_bytes(self.dump_payload(obj))
    rv = self.make_signer(salt).sign(payload)
    if self.is_text_serializer:
        rv = rv.decode("utf-8")
    return rv




File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\url_safe.py",line 42,in dump_payload

                original_error=e,
            )
    return super(URLSafeSerializerMixin, self).load_payload(json, *args, **kwargs)

def dump_payload(self, obj):
    json = super(URLSafeSerializerMixin, self).dump_payload(obj)
    is_compressed = False
    compressed = zlib.compress(json)
    if len(compressed) < (len(json) - 1):
        json = compressed
        is_compressed = True



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\itsdangerous\serializer.py",line 99,in dump_payload

def dump_payload(self, obj):
    """Dumps the encoded object. The return value is always bytes.
    If the internal serializer returns text, the value will be
    encoded as UTF-8.
    """
    return want_bytes(self.serializer.dumps(obj, **self.serializer_kwargs))

def make_signer(self, salt=None):
    """Creates a new instance of the signer to be used. The default
    implementation uses the :class:`.Signer` base class.
    """



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\tag.py",line 296,in dumps


    return self.tags[key].to_python(value[key])

def dumps(self, value):
    """Tag the value and dump it to a compact JSON string."""
    return dumps(self.tag(value), separators=(',', ':'))

def loads(self, value):
    """Load data from a JSON string and deserialized any tagged objects."""
    return loads(value, object_hook=self.untag)



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py",line 179,in dumps

default is controlled by the ``JSON_AS_ASCII`` configuration variable
and can be overridden by the simplejson ``ensure_ascii`` parameter.
"""
_dump_arg_defaults(kwargs)
encoding = kwargs.pop('encoding', None)
rv = _json.dumps(obj, **kwargs)
if encoding is not None and isinstance(rv, text_type):
    rv = rv.encode(encoding)
return rv





File "D:\Programe\Anaconda\lib\json\__init__.py",line 238,in dumps

    cls = JSONEncoder
return cls(
    skipkeys=skipkeys, ensure_ascii=ensure_ascii,
    check_circular=check_circular, allow_nan=allow_nan, indent=indent,
    separators=separators, default=default, sort_keys=sort_keys,
    **kw).encode(obj)


_default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None)





File "D:\Programe\Anaconda\lib\json\encoder.py",line 199,in encode

        else:
            return encode_basestring(o)
    # This doesn't pass the iterator directly to ''.join() because the
    # exceptions aren't as detailed.  The list call should be roughly
    # equivalent to the PySequence_Fast that ''.join() would do.
    chunks = self.iterencode(o, _one_shot=True)
    if not isinstance(chunks, (list, tuple)):
        chunks = list(chunks)
    return ''.join(chunks)

def iterencode(self, o, _one_shot=False):



File "D:\Programe\Anaconda\lib\json\encoder.py",line 257,in iterencode

    else:
        _iterencode = _make_iterencode(
            markers, self.default, _encoder, self.indent, floatstr,
            self.key_separator, self.item_separator, self.sort_keys,
            self.skipkeys, _one_shot)
    return _iterencode(o, 0)

def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
    _key_separator, _item_separator, _sort_keys, _skipkeys, _one_shot,
    ## HACK: hand-optimized bytecode; turn globals into locals
    ValueError=ValueError,



File "D:\Computing Science\Year 3\Software Engineering 2\Coursework\Software-Engineering-2-Coursework\venv\lib\site-packages\flask\json\__init__.py",line 81,in default

        return http_date(o.timetuple())
    if isinstance(o, uuid.UUID):
        return str(o)
    if hasattr(o, '__html__'):
        return text_type(o.__html__())
    return _json.JSONEncoder.default(self, o)


class JSONDecoder(_json.JSONDecoder):
"""The default JSON decoder.  This one does not change the behavior from
the default simplejson decoder.  Consult the :mod:`json` documentation



File "D:\Programe\Anaconda\lib\json\encoder.py",line 180,in default

            # Let the base class default method raise the TypeError
            return JSONEncoder.default(self, o)

    """
    raise TypeError("Object of type '%s' is not JSON serializable" %
                    o.__class__.__name__)

def encode(self, o):
    """Return a JSON string representation of a Python data structure.

    >>> from json.encoder import JSONEncoder


TypeError: Object of type 'OperationalError' is not JSON serializable

代码:

from flask import Flask, render_template, session, redirect,request, flash,
session, url_for
from functools import wraps

import sqlite3
from sqlite3 import Error

import pdb

app = Flask( __name__ )
app.secret_key = "super secret key"


def SQL_Connect(db_file):
    try:
        conn = sqlite3.connect(db_file)
        return conn
    except Error as e:
        print(e)

    return None


# SQL_Create - Create the tables for the SQL database, only needs to be ran     once
def SQL_Create(conn):
    cur = conn.cursor()

    with open('SQL.sql') as fp:
        cur.executescript(fp.read())


    def SQL_Test(conn):
    cur = conn.cursor()
    cur.execute("SELECT * FROM users")

    rows = cur.fetchall()

    for row in rows:
        print(row)


def SQL_GetUserByID(conn, id):
    cur = conn.cursor()
    cur.execute("SELECT firstname FROM users WHERE userid = " + str( id ) )

    result = cur.fetchall()

    # I am awful code, please fix me
    return str( result[0][0] )



def SQL_Threads(conn):
    cur = conn.cursor()
    cur.execute("SELECT * FROM reviews")

    rows = list(cur)

    list_of_lists = [list(elem) for elem in rows]

    for row in list_of_lists:
        AuthorID = row[4]
        AuthorName = SQL_GetUserByID(conn, AuthorID )

        row[4] = AuthorName

        return list_of_lists


def SQL_Load():
    database = "database.db"

    conn = SQL_Connect(database)
    with conn:
        # SQL_Create(conn)
        SQL_Test(conn)

    return conn


@app.route( "/SQL_AddUser", methods=["POST"] )
    def SQL_AddUser():
    Connection = SQL_Load()

    firstname2 = request.form['inputName']
    lastname2 = request.form['inputSurname']
    email2 = request.form['inputEmail']
    password2 = request.form['inputPassword']

    cur = Connection.cursor()
    cur.execute("INSERT INTO users (firstname, lastname, email, password)     VALUES(?, ?, ?, ?)",(firstname2,lastname2,email2,password2))
    Connection.commit()

    session['logged_in'] = True
    session['sessionEmail'] = email2

    return render_template("index.html")


@app.route('/index')
@app.route("/")
def index():
    Connection = SQL_Load()
    LoadReviews = SQL_Threads(Connection)

    Title = LoadReviews[0][1]
    Date = LoadReviews[0][2]
    Rating = LoadReviews[0][3]
    Author = LoadReviews[0][4]
    Text = LoadReviews[0][5]

    return render_template( "index.html", title = Title, date = Date, rating = Rating, author = Author, text = Text )


@app.route('/login', methods=["GET", "POST"])
def login():
    error = ''
    try:
        connection = SQL_Load()
        cur = connection.cursor()
        if request.method == "POST":

            data = cur.execute("SELECT password FROM users WHERE email= (%s)",(request.form['inputEmail']))

            if request.form['password'] == data:
                session['logged_in'] = True
                session['sessionEmail'] = request.form['inputEmail']

                flash("You are now logged in")
                return redirect(url_for("/"))

            else:
                error = "Invalid credentials, try again."

        return render_template("login.html", error=error)

    except Exception as e:
        flash(e)
        error = "Invalid credentials, try again."
        return render_template("login.html", error=error)


@app.route('/register')
def register():
    return render_template("register.html")


@app.route("/logout/")
def logout():
    if 'logged_in' in session:
        session.clear()
        flash("You have been logged out!")
        return redirect(url_for('index'))
    else:
        flash("You need to login first")
        return redirect(url_for('login'))


if __name__ == "__main__":
    app.run(debug=True)

我知道目前代码很乱,对此感到抱歉。我到处搜索,没有运气。

1 个答案:

答案 0 :(得分:0)

您的代码中似乎有两个独立的错误,第一个是在登录功能中的sql中,第二个是在错误处理代码中,这就是为什么您看到的错误消息与初始错误无关。第一个错误是在语句中

data = cur.execute("SELECT password FROM users WHERE email= (%s)",(request.form['inputEmail']))

python sqlite3模块使用?作为参数占位符而不是%s。 execute函数的第二个参数也必须是可迭代的,因为只有一个参数,其后需要有一个逗号,以便python解释器知道周围的括号表示一个元组。下面的代码应该工作< / p>

data = cur.execute("SELECT password FROM users WHERE email= ?", (request.form['inputEmail'],))

这里的错误导致一个sqlite3.OperationalError,您将用“ Exception as e例外”语句捕获该错误。然后,您将错误对象直接传递给flask flash函数而不是字符串,因此,烧瓶错误消息表明OperationalError类型的对象不可序列化。我建议完全避免使用exception语句,而将异常处理限制为仅知道该函数中可能发生的特定异常。您可以根据烧瓶文档http://flask.pocoo.org/docs/1.0/patterns/errorpages/设置自定义错误处理程序,以处理所有意外错误,这比捕获每个函数中的所有处理程序更安全。