美文网首页
FastAPI+SQLServer 中文乱码问题

FastAPI+SQLServer 中文乱码问题

作者: RedB | 来源:发表于2022-02-08 23:12 被阅读0次

    因为在FastAPI相关博客里没有搜到答案,于是分享出来~
    最近在用FastAPI给App写一个简单的登录注册系统的API,明明注册请求的时候发送的中文没问题,但是登录后获取用户信息时,返回的就是乱码,如图


    我的Sqlalchemy的Model写法如下:

    class User(Base):
        __tablename__ = "users"
        id = 略
        phone = 略
        hashed_password = Column(String)
        name = Column(String) # 此字段乱码
    

    一共尝试了三种方案,其中第一种方案可行:

    1. Column(String)改为Column(NVARCHAR),可行,参考自《pymssql读取varchar字段中文显示乱码的问题分析》
    2. 修改排序规则为Chinese_PRC_CI_AS,但我之前已经设置了所以没用上,如有需要可参考《sqlserver乱码问题解决》
    3. 修改pymssql的url,在末尾加上字符集?charset=utf8,即create_engine('mssql+pymssql://username:password@hostname:port/dbname?charset=utf8'),不可行

    最后解释一下原理:为什么把Column(String)改成把Column(NVARCHAR)就可以?
    因为,如果定义Model时用Column(String),实际的数据类型是VARCHAR(MAX);如果用Column(NVARCHAR),数据类型是NVARCHAR(MAX),如下图。

    SQL Management Studio截图

    NVARCHAR与VARCHAR的区别:

    • NVARCHAR:可变长度 Unicode 字符数据(所有的字符都用两个字节表示,即英文字符也是用两个字节表示,可解决题);通过查看源码,它继承的是Unicode类,而Unicode类是在String类基础上增加了一些参数。
    • VARCHAR:可变长度非 Unicode 字符数据(英文字符1字节,中文字符2字节);通过查看源码,它继承的是String类。
    # sqltypes.py
    class Unicode(String):
        __visit_name__ = "unicode"
        def __init__(self, length=None, **kwargs):
            kwargs.setdefault("_expect_unicode", True)
            kwargs.setdefault("_warn_on_bytestring", True)
            super(Unicode, self).__init__(length=length, **kwargs)
    

    *关于VARCHAR和NVARCHAR,具体可参考这两篇:《varchar和Nvarchar区别》《char、varchar、text和nchar、nvarchar、ntext的区别》

    相关文章

      网友评论

          本文标题:FastAPI+SQLServer 中文乱码问题

          本文链接:https://www.haomeiwen.com/subject/kgxikrtx.html