sqlalchemy 中的点类型?

问题描述 投票:0回答:4

我在 Postgres 中发现了关于点类型的信息:http://www.postgresql.org/docs/current/interactive/datatype-geometric.html

有这个的 SQLAlchemy 版本吗?

我以这种方式存储值:(40.721959482,-73.878993913)

python postgresql flask sqlalchemy flask-sqlalchemy
4个回答
9
投票

您可以使用 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'))

3
投票

您可以扩展

UserDefinedType
来实现您想要的。

这是我发现的一个示例,它非常接近您想要子类化的内容

UserDefinedType

请注意,Mohammad Amin 的答案仅当您的点旨在成为地理点(纬度和经度限制)时才有效。如果您想表示平面上的任何点,则它不适用。另外,在这种情况下,您需要安装 PostGIS 扩展,如果您正在使用地理点,我鼓励您安装 PostGIS 扩展,因为它提供了很多实用程序和额外功能。


1
投票

我发现这是对穆罕默德的答案的轻微修改。

是的,我需要通过 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)


1
投票

这是一个在 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)
© www.soinside.com 2019 - 2024. All rights reserved.