You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MikroORM+PostGIS自定义Point类型查询报错:ST_AsText函数不存在

解决MikroORM结合PostGIS查询时ST_AsText函数不存在的问题

问题根源

你当前的实现是适配MySQL的,而PostgreSQL+PostGIS的地理类型体系和MySQL完全不同:

  • 你指定的point是PostgreSQL原生几何类型,不兼容PostGIS的ST_系列函数
  • PostGIS的地理点类型是geometry(Point, SRID),需要用PostGIS专属函数处理

修正后的自定义PointType实现

export class Point {
  constructor(
    public latitude: number,
    public longitude: number,
  ) {}
}

export class PointType extends Type<Point | undefined, string | undefined> {
  // 转换为数据库存储的PostGIS Geometry类型
  convertToDatabaseValue(value: Point | undefined): string | undefined {
    if (!value) return value;
    // 使用ST_MakePoint构造PostGIS点,指定SRID为4326(WGS84坐标系)
    return `ST_SetSRID(ST_MakePoint(${value.longitude}, ${value.latitude}), 4326)`;
  }

  // 从数据库返回的WKT转换为Point对象
  convertToJSValue(value: string | undefined): Point | undefined {
    if (!value) return undefined;
    // 匹配WKT格式,比如"POINT(116.397 39.908)"
    const match = value.match(/POINT\((-?\d+(\.\d+)?) (-?\d+(\.\d+)?)\)/i);
    if (!match) return undefined;
    // 注意PostGIS的WKT是 经度 纬度 顺序
    return new Point(+match[3], +match[1]);
  }

  // 查询时将Geometry转为WKT供JS解析
  convertToJSValueSQL(key: string): string {
    return `ST_AsText(${key})`;
  }

  // 插入/更新时将WKT转为Geometry
  convertToDatabaseValueSQL(key: string): string {
    return `ST_GeomFromText(${key}, 4326)`;
  }

  // 数据库字段类型设为PostGIS的geometry(Point, 4326)
  getColumnType(): string {
    return 'geometry(Point, 4326)';
  }
}

实体类调整

确保point字段的类型正确,若不需要单独存储经纬度可移除冗余字段:

@Entity()
export class Event {
  @Property({ nullable: true })
  location: string;

  // 可选:不需要单独存经纬度可删除这两个字段
  @Property({ nullable: true })
  latitude: number;

  @Property({ nullable: true })
  longitude: number;

  @Property({ type: PointType, nullable: true })
  point: Point;
}

数据库迁移注意事项

  1. 确保当前数据库已启用PostGIS扩展:执行CREATE EXTENSION IF NOT EXISTS postgis;
  2. 生成并运行MikroORM迁移,将原point字段类型从point改为geometry(Point, 4326)

验证

重新运行查询后,MikroORM会生成适配PostGIS的SQL,使用ST_AsText(e0.point)读取geometry字段,不会再出现函数不存在的错误。

内容的提问来源于stack exchange,提问作者drogon98

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:45:05