如何使用带有空间列的SQLalchemy在mysql中创建表?

时间:2017-12-10 19:26:55

标签: python python-3.x sqlalchemy geoalchemy2

我正在尝试使用SQLalchemy和geoalchemy2创建一个表,如下所示:

class RLocModel(Base):
    __tablename__ = 'rloc'
    id = Column(Integer, primary_key=True)
    loc = Column(Geometry('POINT'))                     

这是针对mysql数据库的(实际上是AWS mysql兼容的Aurora数据库)。

我得到如下例外:

(_mysql_exceptions.ProgrammingError) (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(POINT,-1), \n\tPRIMARY KEY (id)\n)' at line 3") [SQL: '\nCREATE TABLE rloc (\n\tid INTEGER NOT NULL AUTO_INCREMENT, \n\tloc geometry(POINT,-1), \n\tPRIMARY KEY (id)\n)\n\n']

我不确定它是否表达了正确的方言。

我可以手动执行此操作:

CREATE TABLE `geo` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `loc` geometry NOT NULL,
  PRIMARY KEY (`id`),
  SPATIAL KEY `loc` (`loc`)
) ENGINE=InnoDB AUTO_INCREMENT=11905 DEFAULT CHARSET=latin1;

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

I had the same issue using a MySql database. According to documentation后如何将功能从另一个Pahe加载到当前页面:

  

注意:   除了PostgreSQL / PostGIS,GeoAlchemy 2目前不支持其他方言。

您可以做的是创建自定义Point类型:

from sqlalchemy import func
from sqlalchemy.types import UserDefinedType

class Point(UserDefinedType):
    def get_col_spec(self):
        return "POINT"

    def bind_expression(self, bindvalue):
        return func.ST_GeomFromText(bindvalue, type_=self)

    def column_expression(self, col):
        return func.ST_AsText(col, type_=self)

现在,您只需在模型中使用此自定义类型:

class RLocModel(Base):
    __tablename__ = 'rloc'
    id = Column(Integer, primary_key=True)
    loc = Column(Point, nullable=False)

然后您可以像这样使用模型:

geo = RLocModel()
geo.loc = 'POINT(0 0)'

答案 1 :(得分:0)

如果有人正在寻找 SRID 支持,以下是@adrihanu 的支持答案的修改版本。

from sqlalchemy import func
from sqlalchemy.types import UserDefinedType

class Point(UserDefinedType):
    def get_col_spec(self):
        return "POINT SRID 4326"

    def bind_expression(self, bindvalue):
        return func.ST_GeomFromText(bindvalue, 4326, type_=self)

    def column_expression(self, col):
        return func.ST_AsText(col, type_=self)

其他都一样

class RLocModel(Base):
    __tablename__ = 'rloc'
    id = Column(Integer, primary_key=True)
    loc = Column(Point, nullable=False)

使用中

geo = RLocModel()
geo.loc = 'POINT(40.7647919738352, -73.99207372979897)'