" TypeError:没有编码的字符串参数" Flask和SQLAlchemy

时间:2018-03-08 22:30:50

标签: python sqlite sqlalchemy

我正在慢慢尝试使用Flask,Marshmallow,SQLAlchemy和SQLite3构建一个小型Rest API。在最近的某个时刻,我的简单" Get"对users表的调用似乎有效,但后来我在尝试填充时反复尝试相同的参数。

错误:" TypeError:没有编码的字符串参数"

在我的浏览器中尝试localhost:5000 / users时会发生这种情况。确切的行是96" users = Users.query.all()"确切的函​​数似乎是根据stacktrace的SQLAlchemy.query()(我在下面的帖子中)。

我通过许多教程以不同方式尝试了这种简单方法,但无济于事。这可能是Python 2对3的事情吗?我的少量代码似乎非常准确地有多少教程。

代码(唯一的模块):

from flask import Flask
from flask_script import Manager, Server
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Schema
from marshmallow import fields


app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///../campus.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = 'False'

db = SQLAlchemy(app)
manager = Manager(app)

manager.add_command("runserver", Server(
use_debugger=True,
use_reloader=True,
host='0.0.0.0'))


class Users(db.Model):
    user_id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    is_admin = db.Column(db.Integer, nullable=False)
    password = db.Column(db.Integer, nullable=False)
    picture = db.Column(db.LargeBinary)

    def __repr__(self):
        return '<User %r>' % self.username


class Pins(db.Model):
    pin_id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)
    parent_id = db.Column(db.Integer, nullable=False)
    user_id = db.Column(db.Integer, nullable=False)
    master_comment = db.Column(db.Integer, nullable=False)
    x_coord = db.Column(db.Float, nullable=False)
    y_coord = db.Column(db.Float, nullable=False)
    picture = db.Column(db.LargeBinary)
    likes = db.Column(db.Integer, nullable=False)
    dislikes = db.Column(db.Integer, nullable=False)
    tags = db.Column(db.String(150))


class Comments(db.Model):
    comment_id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)
    parent_id = db.Column(db.Integer, nullable=False)
    user_id = db.Column(db.Integer, nullable=False)
    text = db.Column(db.String, nullable=False)
    likes = db.Column(db.Integer, nullable=False)
    dislikes = db.Column(db.Integer, nullable=False)


class UserSchema(Schema):
    user_id = fields.Int()
    username = fields.Str()
    is_admin = fields.Int()
    password = fields.Int()
    picture = fields.Raw()


class PinsSchema(Schema):
    pin_id = fields.Int()
    parent_id = fields.Int()
    user_id = fields.Int()
    master_comment = fields.Int()
    x_coord = fields.Float()
    y_coord = fields.Float()
    picture = fields.Raw()
    likes = fields.Int()
    dislikes = fields.Int()
    tags = fields.Str()


class CommentsSchema(Schema):
    comment_id = fields.Int()
    parent_id = fields.Int()
    user_id = fields.Int()
    text = fields.Str()
    likes = fields.Int()
    dislikes = fields.Int()


user_schema = UserSchema()
users_schema = UserSchema(many=True)

pin_schema = PinsSchema()
pins_schema = PinsSchema(many=True)

comment_schema = PinsSchema()
comments_schema = PinsSchema(many=True)


@app.route("/users")
def get_users():
    users = Users.query.all()
    return user_schema.jsonify(users)


if __name__ == '__main__':
    db.create_all()
    app.run()

我的追溯:

    Traceback (most recent call last):
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "SIUCampusMapServer.py", line 96, in get_users
    users = Users.query.all()
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2737, in all
    return list(self)
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/orm/loading.py", line 98, in instances
    util.raise_from_cause(err)
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 187, in reraise
    raise value
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/orm/loading.py", line 79, in instances
    rows = [proc(row) for row in fetch]
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/orm/loading.py", line 79, in <listcomp>
    rows = [proc(row) for row in fetch]
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/orm/loading.py", line 493, in _instance
    loaded_instance, populate_existing, populators)
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/orm/loading.py", line 593, in _populate_full
    dict_[key] = getter(row)
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/engine/result.py", line 93, in __getitem__
    return processor(self._row[index])
  File "/home/joshuasonn/PycharmProjects/SIUCampusMapServer/venv/lib/python3.6/site-packages/sqlalchemy/sql/sqltypes.py", line 902, in process
    value = bytes(value)
TypeError: string argument without an encoding

任何帮助将不胜感激!我尝试过多种方式的重写,并经历了相当多的stackoverflow帖子和github问题试图解决这个问题。

1 个答案:

答案 0 :(得分:1)

长话短说,您在用户表的图片列的某行中有文字数据。

这是可能的,因为与静态相比,许多其他SQL实现SQLite has dynamic typing不同。您为列提供的类型定义了其affinity,或者换句话说,该列中存储的数据的推荐类型,但它是建议,而不是要求。最后,您可以在INTEGER列中使用文本数据,或者在您的情况下使用BLOB列中的TEXT storage class创建数据。

一个例子:

In [2]: class User(Base):
   ...:     __tablename__ = 'user'
   ...:     id = Column(Integer, primary_key=True)
   ...:     picture = Column(LargeBinary)
   ...:     

In [3]: metadata.create_all()
...
2018-03-09 09:33:37,785 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE user (
        id INTEGER NOT NULL, 
        picture BLOB, 
        PRIMARY KEY (id)
)
...

In [4]: engine.execute("insert into user (picture) values ('BANG!')")
Out[4]: <sqlalchemy.engine.result.ResultProxy at 0x7f7ad8bcc278>

尝试获取用户并不能很好地结束:

In [5]: session.query(User).all()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-f1275abaf1fd> in <module>()
----> 1 session.query(User).all()

...

~/Work/SO/lib/python3.6/site-packages/sqlalchemy/sql/sqltypes.py in process(value)
    900             def process(value):
    901                 if value is not None:
--> 902                     value = bytes(value)
    903                 return value
    904             return process

TypeError: string argument without an encoding

您必须完成用户数据并手动修复。使用typeof()功能,您可以找到有问题的行:

In [9]: session.query(User.id).\
   ...:     filter(func.typeof(User.picture) == 'text').\
   ...:     all()
Out[9]: [(1)]