SQLAlchemy 查询未返回大型文本字段的全部内容

5 投票
1 回答
2818 浏览
提问于 2025-04-17 06:28

首先,给大家介绍一下我的环境:

  • 我使用 MSSMS 作为我的数据库管理工具。
  • 我在用 Django 1.3。
  • 我使用 SQLAlchemy。

我在数据库里有一个文本字段,没有最大长度限制。里面的文本长度达到了 890591 个字符。

当我用 SQLAlchemy 获取这个字段时,它被截断到了 64512 个字符。我尝试了其他几个大行数据,也是总是截断到 64512。

SELECT @@TEXTSIZE 返回的值很离谱,大约是 160 万,所以这不是问题。如果我执行 SELECT DATALENGTH(field),它返回的长度是正确的 890591。所以看起来问题不在数据库,而是在 SQLAlchemy 上。或者可能是 Python 的某个限制。

有没有什么想法?我感觉快要无计可施了。

编辑:这是一些额外的信息,大家要求的:

操作系统:Debian 5.0.9

SQLAlchemy 版本:0.7.3

数据库:MS Sql Server 2008

数据库连接:mssql+pymssql://name:password@server/dbname

pymssql 版本:1.0.2

相关模型:

class RACReport(Base):
    __tablename__ = 'RACReport'
    id                      = Column(properUUID(), primary_key=True, nullable=False, default=genuuid4, server_default=text('NEWID()'))
    client_id               = Column(properUUID(), ForeignKey(Client.id), nullable=False)
    rawdata                 = Column(Text(), nullable=True)
    rawtime                 = Column(DateTime(), nullable=True, default=datetime.datetime.now())
    processeddata           = Column(Text(), nullable=True)
    processedtime           = Column(DateTime(), nullable=True)
    reportstartdate         = Column(DateTime(), nullable=False)
    reportenddata           = Column(DateTime(), nullable=False)
    numberofdocs            = Column(Integer(), nullable=True)
RACReport.__table__.schema='rac'

class properUUID(st.TypeDecorator):
    impl = mssql.MSUniqueIdentifier
    def process_result_value(self, value, dialect):
        if value:
            return str(uuid.UUID(bytes_le=value))

def genuuid4():
    return str(uuid.uuid4())

rawdata 和 processdata 是他遇到问题的两个字段。

这是一个测试查询和回显:

rac.session.query(rac.RACReport).filter(rac.RACReport.id=='8fb76cb7-d752-45af-a20a-3b85d5e7b8a6').all()

2011-11-17 09:39:46,890 INFO sqlalchemy.engine.base.Engine SELECT [RACReport_1].id AS [rac_RACReport_id], [RACReport_1].client_id AS [rac_RACReport_client_id], [RACReport_1].rawdata AS [rac_RACReport_rawdata], [RACReport_1].rawtime AS [rac_RACReport_rawtime], [RACReport_1].processeddata AS [rac_RACReport_processeddata], [RACReport_1].processedtime AS [rac_RACReport_processedtime], [RACReport_1].reportstartdate AS [rac_RACReport_reportstartdate], [RACReport_1].reportenddate AS [rac_RACReport_reportenddate] FROM rac.[RACReport] AS [RACReport_1] WHERE [RACReport_1].id = %(id_1)s 2011-11-17 09:39:46,890 INFO sqlalchemy.engine.base.Engine {'id_1': '8fb76cb7-d752-45af-a20a-3b85d5e7b8a6'}

1 个回答

4

我对*nix系统如何连接SQL Server了解不多,但简单搜索一下发现问题可能和FreeTDS的配置有关:

  1. 在StackOverflow上有个相关的问题:数据在64512个字符处结束 - MSSQL // PHP // OPENSuSE // APACHE2
  2. 还有一个问答摘自这里

我的文本数据被截断了,或者导致客户端崩溃。

文本数据类型和char、varchar类型是不同的。文本列的最大数据长度是由textsize连接选项决定的。微软在他们的文档中声称默认的textsize是4000个字符,但实际上他们的实现并不一致。有时文本列返回的大小竟然是4GB!

最好的解决办法是在建立连接时确保将textsize选项设置为一个合理的值。例如:

1> set textsize 10000 
2> go 

另外,请查看freetds.conf中的文本大小选项。


顺便提一下:你似乎在使用一个相当过时的pymssql版本。

撰写回答