[英]Why is my VARCHAR truncated to 255 characters? How do I fix this?
设置:
我正在使用以下组件:
...针对 MSSQL Server 2014。
问题:
假设我有一个只包含 2 列的表格:
我的 SQLAlchemy 模型如下所示:
from sqlalchemy.dialects.mssql.base import VARCHAR
MyText(Base):
id = Column(Integer, primary_key=True)
my_text = Column(VARCHAR())
当我尝试像这样创建一个新的文本条目并且我的文本长度超过 255 个字符时,该字符串会在 255 处以静默方式截断。
my_text='REALLY LONG STRING THAT IS LONGER THAN 255. E.g.: 6000+ characters. Assume my string is 558 bp long.'
print(len(my_text)) # Gives 558 bp.
new_text = MyText(my_text=my_text)
print(len(new_text.my_text)) # Gives 558 bp.
db_s.add(new_text)
print(len(new_text.my_text)) # Gives 558 bp.
db_s.commit()
print(len(new_text.my_text)) # Gives 255 bp now after commit.
起初,我认为这是在写入数据库时引起的。 但我发现这是在查询时引起的(请阅读下文)。
问题:
1.) 为什么会这样?
我认为这与驱动程序(例如:unixodbc 2.3.4、FreeTDS 1.12)有关,但我并不完全是在发生这种情况的地方。
2.) 更重要的是,我该如何解决这个问题?
这些问题是相关但不同的:
上面的问题是我没有使用MYSQL。 所以提供的解决方案不能解决问题。
unixODBC/FreeTDS 结果被截断为 255 个字符
该线程中没有提供解决方案。
关于这一点,应该注意的是,我的字符串通常可以超过 6000 个字符(因为我正在处理长 DNA 序列)。 我真的很感激任何解决截断问题的方法。
更新 (2017-10-12):
从昨天开始,我做出了一些非凡但同样令人费解的发现。
# Connecting via pyodbc direct connection using just some helper functions to make things more convenient.
con_str = create_connection_string(DATABASE='test')
cur = make_connection_db(connection_str=con_str)
for row in cur.execute('SELECT Text.my_text, len(Text.my_text) FROM [test].[dbo].[Text]'):
print(row)
print(len(row[0]))
这给了我一个 558 个字符长的字符串(见下文)。
('ATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATG',
558)
558
现在使用 SQL Alchemy 但仍然直接使用 sql 语句。
# Using SqlAlchemy connection with direct SQL query.
eoi_engine = create_engine(
"mssql+pyodbc://user:somepw@db:1234/test?driver=FreeTDS")
s_con = eoi_engine.connect()
s_res = s_con.execute('SELECT Text.my_text, len(Text.my_text) FROM [test].[dbo].[Text]')
for row in s_res:
print(row)
print(len(row[0])
这给了我一个字符串,它声称它有 558 个字符长,但实际上它只有 255 个字符长。
('ATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATGATG',
558)
255
最后一个场景:
# Using SQLAlchemy full-stack.
Session = sessionmaker()
s = Session(bind=s_con)
fs_res = s.query(DNAPtsSeq).filter().all()
for row in fs_res:
print(row)
print(len(row.nt_seq))
这给了我一个只有 255 个字符长的字符串。
所以总结一下:
我不知道为什么我只在使用 SQLAlchemy 查询时收到此错误。 有谁知道原因? 我该如何解决这种行为? (我知道解决方法是使用直接 sql 查询...)
就我而言,事实证明存在几个复合错误,我将列出以供后代使用,以防其他人遇到与我相同的问题:
即使将 VARCHAR(8000) 更改为 VARCHAR() 也不能解决我的问题。 事实证明,MSSQL VARCHAR(MAX) 是高度非标准的。 一个模糊的参考,让我发现有一个不同的 VARCHAR 只用于 MSSQL。 如果您从以下位置导入 VARCHAR:
from sqlalchemy.dialects.mssql.base import VARCHAR
...然后您可以将您的文本字段声明为 VARCHAR() ,它等于 MSSQL 中的 VARCHAR(Max) 。
http://docs.sqlalchemy.org/en/latest/dialects/mssql.html
这将截断限制增加到 4096 个字符,但没有解决。
我试图在这里破译以下答案:
不幸的是,更改文本大小缓冲区并没有消除 4096 的截断限制。在我的情况下,我还必须在查询数据库之前使用 SQLAlchemy 的 sql 语句:
db_s.execute('Set TEXTSIZE {0}'.format(SOME_BIG_NUMBER_LIKE_20000)
谢谢你的旧帖子
我的解决方案是在 SELECT 语句中使用CAST(FIELDNAME as NVARCHAR(4000))
如果我使用CAST(FIELDNAME as NVARCHAR)
,SQLAlchemy 将剪切字符串
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.