使用 sqlalchemy 核心调用 GeomFromText 和其他此类函数

Posted

技术标签:

【中文标题】使用 sqlalchemy 核心调用 GeomFromText 和其他此类函数【英文标题】:calling GeomFromText and other such functions using sqlalchemy core 【发布时间】:2016-04-27 23:41:28 【问题描述】:

我在 python 中使用 mysql 数据库。我有一个使用 MySQL 几何扩展的表,所以我需要在更新语句期间调用 GeomFromText MySQL 函数,如下所示:

UPDATE myTable SET Location=GeomFromText('Point(39.0 55.0)') where id=1;
UPDATE myTable SET Location=GeomFromText('Point(39.0 55.0)') where id=2;

最初,我使用的是低级 MySQLdb 库。我正在切换到使用 SQLAlchemy 核心库(出于速度和其他原因,我不能使用 SQLAlchemy ORM)。

如果我直接使用较低级别的 MySQLdb 库,我会这样做:

import MySQLdb as mysql
commandTemplate = "UPDATE myTable SET Location=GeomFromText(%s) where id=%s"
connection = mysql.connect(host="myhost",user="user",passwd="password",db="my_schema")
cursor = connection.cursor(mysql.cursors.DictCursor)
data = [
    ("Point(39.0 55.0)",1),
    ("Point(39.0 55.0)",2),
]
cursor.executemany(commandTemplate,data)

如何获得与 SQLAlchemy 核心相同的功能?

如果没有 GeomFromText,我认为它看起来像这样(感谢this answer):

from sqlalchemy.sql.expression import bindparam

updateCommand = myTable.update().where(id=bindparam("idToChange"))
data = [
    'idToChange':1,'Location':"Point(39.0 55.0)",
    'idToChange':2,'Location':"Point(39.0 55.0)",
]
connection.execute(updateCommand,data)

我不能直接将“Point(39.0 55.0)”替换为“GeomFromText('Point(39.0 55.0)')”,否则我会得到:

Cannot get geometry object from data you send to the GEOMETRY field

【问题讨论】:

【参考方案1】:

到目前为止,我发现的最简单的方法是使用 text(即构造 TextClause 对象),它可以让您(几乎)按字面意思输入 SQL 语法。

我的例子是这样的:

from sqlalchemy.sql.expression import bindparam
from sqlalchemy import text

updateCommand = myTable.update().where(id=bindparam("idToChange"))
valuesDict = 'idToChange':':idToChange', 
              'Location':text("GeomFromText(:_location)")

updateCommand = updateCommand.values(**valuesDict)
data = [
    'idToChange':1,'_location':"Point(39.0 55.0)",
    'idToChange':2,'_location':"Point(39.0 55.0)",
]
#see the MySQL command as it will be executed (except for data)
print(connection.compile(bind=connection))
#actually execute the statement
connection.execute(updateCommand,data)

重点:

调用updateCommand.values 替换了SQL 子句的VALUES 部分。只有您作为 kwargs 提供给此调用的列实际上会被放入最终的 UPDATE 语句中

updateCommand.values 的关键字参数的值可以是一组文字数据(如果您只更新一行),也可以是给出data 中键名的字符串最终将与命令一起传递给connection.execute 方法的字典。使用的格式是 ColumnName=":dictionaryKeyName"。

关键字参数的值也可以是text 子句的结果,它本身可以包含相同“:dictionaryKeyName”格式的字段名。

【讨论】:

以上是关于使用 sqlalchemy 核心调用 GeomFromText 和其他此类函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 SQLAlchemy 核心进行自动连接?

使用核心 SQLAlchemy 插入和更新

python 使用sqlalchemy核心的SQL查询

SQLAlchemy 核心连接上下文管理器

Redshift:DateDiff 调用上的 SqlAlchemy 错误

使用 RoutingSession 时在 sqlalchemy 中调用了两次“get_bind”方法