Tam*_*más 13 python sql python-db-api
我正在实现一个Python本体类,它使用数据库后端来存储和查询本体.数据库模式是固定的(事先指定),但我不知道正在使用什么类型的数据库引擎.但是,我可以依赖数据库引擎的Python接口使用Python DB-API 2.0(PEP 249)的事实.一个直截了当的想法是让用户将符合PEP 249的Connection对象传递给我的本体的构造函数,然后使用各种硬编码的SQL查询来查询数据库:
class Ontology(object):
def __init__(self, connection):
self.connection = connection
def get_term(self, term_id):
cursor = self.connection.cursor()
query = "SELECT * FROM term WHERE id = %s"
cursor.execute(query, (term_id, ))
[...]
Run Code Online (Sandbox Code Playgroud)
我的问题是允许不同的数据库后端支持查询中的不同参数标记,由paramstyle后端模块的属性定义.例如,如果paramstyle = 'qmark',接口支持问号样式(SELECT * FROM term WHERE id = ?); paramstyle = 'numeric'表示数字,位置样式(SELECT * FROM term WHERE id = :1); paramstyle = 'format'表示ANSI C格式的字符串样式(SELECT * FROM term WHERE id = %s).如果我想让我的类能够处理不同的数据库后端,似乎我必须为所有参数标记样式做准备.这似乎打败了我的通用DB API的整个目的,因为我不能使用相同的参数化查询与不同的数据库后端.
有没有办法绕过它,如果是这样,最好的办法是什么?DB API没有指定是否存在通用转义函数,我可以使用该函数清理查询中的值,因此手动执行转义不是一种选择.我不想通过使用更高级别的抽象(例如SQLAlchemy)为项目添加额外的依赖项.
这个Python配方可能会有所帮助.它引入了一个额外的抽象层来包装自己Param类中的参数.
该PyDal项目也可能会接近你想达到什么目的" PyDal能够与符合DBAPI 2.0的任何模块使用相同的paramstyle和时间类型此外,paramstyles和时间类型是可配置的. "
严格来说,问题不是由 DB API 允许这样做引起的,而是由不同的数据库使用不同的 SQL 语法引起的。DB API 模块将精确的查询字符串连同参数一起传递到数据库。“解析”参数标记是由数据库本身完成的,而不是由 DB API 模块完成的。
这意味着如果你想解决这个问题,你必须引入一些更高级别的抽象。如果您不想添加额外的依赖项,则必须自己添加。但是,您可以尝试根据后端模块的 paramstyle 将查询字符串中的参数标记动态替换为所需的参数标记,而不是手动转义和替换。然后将带有参数标记的字符串传递给数据库。例如,您可以在任何地方使用“%s”,如果数据库使用“数字”样式,则可以使用 python 字符串替换将“%s”替换为“:1”、“:2”等。 ..