我的需求是通过python从sql_server中创建的表中获取所有数据。我面临的问题是sql_server中的一列的数据类型是“sql_variant”,在对sql_varinat数据类型进行搜索/研发后,我发现“sql_variant可以保存任何数据(日期,日期时间,字符串) ,整数,浮点数)。
在我的例子中,该列包含日期时间、整数和浮点数。
因此,当我尝试在 python 中获取数据时,出现以下错误:- sqlalchemy.exc.ProgrammingError:(pyodbc.ProgrammingError)('尚不支持 ODBC SQL 类型 -150。column-index=6 type=-150','HY106')(此错误的背景位于:https:// /sqlalche.me/e/20/f405)
我尝试了Python中的所有数据类型(字符串、整数、浮点数、数据时间)来获取数据。但它们都不起作用。
sql_server 代码是:- 创建表表名( [fan_attribute.value] sql_variant NULL );
Python代码是:- 从 sqlalchemy 导入列、整数、字符串、日期时间 从 sqlalchemy.ext.declarative 导入 declarative_base
from datetime import datetime
from sqlmodel import Field, PrimaryKeyConstraint, SQLModel
Base = declarative_base()
class ModelName(Base):
__table_args__ = ({"schema": "can't disclose"})
__tablename__ = "table_name"
value = Column("fan_attribute.value", String)
有没有办法在Python中获取sql_variant列。
如问题中所述,pyodbc 当前无法检索 SQL_VARIANT 列。该问题已在 GitHub here 上讨论,并且已提交补丁 here,但尚未合并。
pymssql 在访问 SQL_VARIANT 列时不会抛出异常,但它遇到与上面引用的问题中的 pyodbc 相同的问题,因为它只返回原始字节,而不指示实际(变体)数据类型是什么:
from sqlalchemy import create_engine
connection_url = "mssql+pymssql://scott:tiger^[email protected]/test"
engine = create_engine(connection_url)
with engine.begin() as conn:
conn.exec_driver_sql("DROP TABLE IF EXISTS sqlvariant_test")
conn.exec_driver_sql("CREATE TABLE sqlvariant_test (val_type varchar(20) primary key, val sql_variant)")
conn.exec_driver_sql("INSERT INTO sqlvariant_test (val_type, val) VALUES ('datetime2', CAST('2024-08-25 12:13:14.01234' AS datetime2))")
conn.exec_driver_sql("INSERT INTO sqlvariant_test (val_type, val) VALUES ('int', 1685221191)")
conn.exec_driver_sql("INSERT INTO sqlvariant_test (val_type, val) VALUES ('varchar', 'Gord')")
with engine.begin() as conn:
result = conn.exec_driver_sql("SELECT val_type, val FROM sqlvariant_test")
for row in result:
print(row.val)
"""
b'\x08\x8bynf\x00\x00\x00\xd7\xb1\x00\x00\x00\x00\x07`'
b'Gord'
b'Gord'
"""
但是,sqlalchemy-pytds方言似乎确实返回了正确的类型:
from sqlalchemy import create_engine
connection_url = "mssql+pytds://scott:tiger^[email protected]/test"
engine = create_engine(connection_url)
with engine.begin() as conn:
conn.exec_driver_sql("DROP TABLE IF EXISTS sqlvariant_test")
conn.exec_driver_sql("CREATE TABLE sqlvariant_test (val_type varchar(20) primary key, val sql_variant)")
conn.exec_driver_sql("INSERT INTO sqlvariant_test (val_type, val) VALUES ('datetime2', CAST('2024-08-25 12:13:14.01234' AS datetime2))")
conn.exec_driver_sql("INSERT INTO sqlvariant_test (val_type, val) VALUES ('int', 1685221191)")
conn.exec_driver_sql("INSERT INTO sqlvariant_test (val_type, val) VALUES ('varchar', 'Gord')")
with engine.begin() as conn:
result = conn.exec_driver_sql("SELECT val_type, val FROM sqlvariant_test")
for row in result:
print(row.val)
"""
2024-08-25 12:13:14.012340
1685221191
Gord
"""
请注意,sqlalchemy-pytds 方言未经 SQLAlchemy 团队测试或认可。