如何创建带自定义Geography类型的SQLModel实例?
问题修复方案
1. 检查自定义Geography类的核心方法实现
自定义UserDefinedType必须正确实现与Python和SQL Server的双向转换逻辑,这是字段赋值为空的核心原因之一:
from sqlalchemy import types from sqlalchemy.sql import expression class Geography(types.UserDefinedType): def get_col_spec(self): return "GEOGRAPHY" # 必须指定Python端对应的类型,确保ORM能识别赋值类型 @property def python_type(self): return str # 将Python值转换为SQL Server可识别的geography格式 def process_bind_param(self, value, dialect): if value is None: return None # 注意:WKT规范中POINT坐标用空格分隔,不是逗号! return expression.func.STGeomFromText(value, 4326) # 将数据库返回的geography对象转为Python可用格式 def process_result_value(self, value, dialect): if value is None: return None return value.STAsText()
2. 确认模型类字段类型关联正确
确保模型中location字段明确绑定自定义的Geography类型,而非默认的字符串或其他类型:
from sqlalchemy import Column, Integer from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class SessionModel(Base): __tablename__ = 'sessions' id = Column(Integer, primary_key=True) location = Column(Geography) # 这里必须用自定义的Geography类型
3. 修正WKT格式错误
你传入的'POINT(1.0, 2.0)'不符合WKT规范——POINT的坐标参数必须用空格分隔,而非逗号。错误格式会导致转换失败,最终字段被设为None:
# 正确写法 session = SessionModel(location='POINT(1.0 2.0)')
4. Pydantic模型的适配(如果使用)
如果用Pydantic做数据校验,需确保字段类型与SQLAlchemy的自定义类型匹配,避免校验时丢失值:
from pydantic import BaseModel, validator class SessionCreate(BaseModel): location: str # 可选:添加WKT格式校验 @validator('location') def validate_wkt(cls, v): if not v.startswith(('POINT(', 'POLYGON(', 'LINESTRING(')): raise ValueError('Invalid WKT format') return v class Config: orm_mode = True
5. 调试排查技巧
- 在
process_bind_param方法中添加打印语句,检查传入的value是否正确接收,是否进入了转换逻辑; - 直接执行SQL语句
SELECT STGeomFromText('POINT(1.0 2.0)', 4326)验证格式是否被SQL Server识别; - 检查数据库表的
location字段是否允许NULL,如果不允许,错误格式会抛出异常,而非静默设为None。
内容的提问来源于stack exchange,提问作者Idan
相关产品推荐
相关产品推荐

