我在 Postgres 中发现了关于点类型的信息:http://www.postgresql.org/docs/current/interactive/datatype-geometric.html
有这个的 SQLAlchemy 版本吗?
我以这种方式存储值:(40.721959482,-73.878993913)
您可以使用 geoalchemy2 这是 sqlalchemy 的扩展,也可以与flask-sqlalchemy 一起使用。
from sqlalchemy import Column
from geoalchemy2 import Geometry
# and import others
class Shop(db.Model):
# other fields
coordinates = Column(Geometry('POINT'))
UserDefinedType
来实现您想要的。
这是我发现的一个示例,它非常接近您想要子类化的内容
UserDefinedType
请注意,Mohammad Amin 的答案仅当您的点旨在成为地理点(纬度和经度限制)时才有效。如果您想表示平面上的任何点,则它不适用。另外,在这种情况下,您需要安装 PostGIS 扩展,如果您正在使用地理点,我鼓励您安装 PostGIS 扩展,因为它提供了很多实用程序和额外功能。
我发现这是对穆罕默德的答案的轻微修改。
是的,我需要通过 geo/sqlalchemy 添加点列
from sqlalchemy import Column
from geoalchemy2 import Geometry
# and import others
class Shop(db.Model):
# other fields
coordinates = Column(Geometry('POINT'))
在我的 PostGIS/Gres 和 PGloader 方面,因为我从 csv 加载,该 csv 将我的纬度和经度点格式化为:
"(40.721959482, -73.878993913)"
我需要在 vim 中按顺序为我的所有条目(有很多)执行一个宏为了强制该列遵循在 PostGIS 中创建点的方式,因此我将 csv 列转换为 point(40.721959482 -73.878993913)
,然后在创建表时将位置列的数据类型设置为几何(点)location geometry(point)
。
这是一个在 SQLAlchemy 中使用本机 PostgreSQL 点类型的工作示例,无需 PostGIS 或其他扩展,基于其他答案中提出的建议:
import sqlalchemy
@dataclass(eq=True, frozen=True, slots=True)
class Coordinate:
"""
Container to hold a geolocation.
"""
lat: float
lng: float
class LatLngType(sqlalchemy.types.UserDefinedType):
"""
Custom SQLAlchemy type to handle POINT columns.
References:
- https://gist.github.com/kwatch/02b1a5a8899b67df2623
- https://docs.sqlalchemy.org/en/14/core/custom_types.html#sqlalchemy.types.UserDefinedType # noqa
"""
# Can do because we made the Coordinate dataclass hashable.
cache_ok = True
def get_col_spec(self):
return "POINT"
def bind_expression(self, bindvalue):
return sqlalchemy.func.POINT(bindvalue, type_=self)
def bind_processor(self, dialect):
"""
Return function to serialize a Coordinate into a database string literal.
"""
def process(value: Coordinate | Tuple[float, float] | None) -> str | None:
if value is None:
return None
if isinstance(value, tuple):
value = Coordinate(*value)
return f"({value.lat},{value.lng})"
return process
def result_processor(self, dialect, coltype):
"""
Return function to parse a database string result into Python data type.
"""
def process(value: str) -> Coordinate | None:
if value is None:
return None
lat, lng = value.strip("()").split(",")
return Coordinate(float(lat), float(lng))
return process
使用方法如下:
class MyModel(Base):
location = Column(LatLngType)