SQLAlchemy 核心 - 如何使 ResultProxy 对模式列名称不区分大小写?
SQLAlchemy core - how to make a ResultProxy case-insensitive wrt Schema column names?
使用SQL Alchemy core时,如何避免后端数据库之间列名更改的错误?我不控制后端,也不需要写信给它们,我只想 select 数据并查看值。
假设您有 create table foo(bar int)
。或者类似的东西。在 SQL 服务器中它将是 create table FOO(BAR int)
执行 select * from FOO
这将在 Oracle、Postgres 和 MS Sqlserver 中正常工作。
但是,Postgres 和 Oracle 将 return sqlalchemy.engine.result.RowProxy 个我可以 print(row.bar)
.
的实例
虽然 SQL 服务器将 return 完全相同的数据,使用完全相同的查询但我必须使用 print(row.BAR)
.
现在,结果列表中的每个 RowProxy 使用一个共享属性 _keymap
将字段名映射到 _row
属性中的位置,该属性携带数据 return 查询该数据库行。
所以,给定一个 _keymap {u'bar': (None, None, 0)}
,它表示元组位置 0 包含 bar,我可以(并且已经这样做)更改为 {u'bar': (None, None, 0),u'BAR': (None, None, 0)}
.
考虑到我可以 print(row.bar)
或 print(row.BAR)
而不必怀疑后端数据库是否存储 bar
或 BAR
.
但是,在针对多个数据库引擎使用 SQL Alchemy 时,抽象列 upper/lower 模式名称似乎是一个相当普遍的问题,这在一般情况下似乎非常有能力。
我错过了什么吗?没有内置的方法吗?
这是使用原始 sql 的 SQL Alchemy,即我的应用程序将查询构建为普通 sql。我不能使用 ORM,这完全超出了范围。我也无法调整数据库后端的配置以使用大名或小名——我无法控制它们。
您可能正在寻找
create_engine(..., case_sensitive=False)
case_sensitive
参数默认为 True。如果设置为 False,结果列匹配时不区分大小写。
In [15]: engine = create_engine('sqlite://', case_sensitive=False)
In [16]: metadata = MetaData()
In [17]: metadata.bind = engine
In [18]: tbl = Table('foo', metadata, Column('BAR', Text))
In [19]: metadata.create_all()
In [22]: engine.execute(tbl.insert().values([('asdf',), ('qwer',)]))
Out[22]: <sqlalchemy.engine.result.ResultProxy at 0x7f03b4ba6b00>
In [23]: row = engine.execute(tbl.select()).fetchone()
In [24]: row
Out[24]: ('asdf',)
In [25]: row.BAR
Out[25]: 'asdf'
In [26]: row.BaR
Out[26]: 'asdf'
In [27]: row.bar
Out[27]: 'asdf'
使用SQL Alchemy core时,如何避免后端数据库之间列名更改的错误?我不控制后端,也不需要写信给它们,我只想 select 数据并查看值。
假设您有 create table foo(bar int)
。或者类似的东西。在 SQL 服务器中它将是 create table FOO(BAR int)
执行 select * from FOO
这将在 Oracle、Postgres 和 MS Sqlserver 中正常工作。
但是,Postgres 和 Oracle 将 return sqlalchemy.engine.result.RowProxy 个我可以 print(row.bar)
.
虽然 SQL 服务器将 return 完全相同的数据,使用完全相同的查询但我必须使用 print(row.BAR)
.
现在,结果列表中的每个 RowProxy 使用一个共享属性 _keymap
将字段名映射到 _row
属性中的位置,该属性携带数据 return 查询该数据库行。
所以,给定一个 _keymap {u'bar': (None, None, 0)}
,它表示元组位置 0 包含 bar,我可以(并且已经这样做)更改为 {u'bar': (None, None, 0),u'BAR': (None, None, 0)}
.
考虑到我可以 print(row.bar)
或 print(row.BAR)
而不必怀疑后端数据库是否存储 bar
或 BAR
.
但是,在针对多个数据库引擎使用 SQL Alchemy 时,抽象列 upper/lower 模式名称似乎是一个相当普遍的问题,这在一般情况下似乎非常有能力。
我错过了什么吗?没有内置的方法吗?
这是使用原始 sql 的 SQL Alchemy,即我的应用程序将查询构建为普通 sql。我不能使用 ORM,这完全超出了范围。我也无法调整数据库后端的配置以使用大名或小名——我无法控制它们。
您可能正在寻找
create_engine(..., case_sensitive=False)
case_sensitive
参数默认为 True。如果设置为 False,结果列匹配时不区分大小写。
In [15]: engine = create_engine('sqlite://', case_sensitive=False)
In [16]: metadata = MetaData()
In [17]: metadata.bind = engine
In [18]: tbl = Table('foo', metadata, Column('BAR', Text))
In [19]: metadata.create_all()
In [22]: engine.execute(tbl.insert().values([('asdf',), ('qwer',)]))
Out[22]: <sqlalchemy.engine.result.ResultProxy at 0x7f03b4ba6b00>
In [23]: row = engine.execute(tbl.select()).fetchone()
In [24]: row
Out[24]: ('asdf',)
In [25]: row.BAR
Out[25]: 'asdf'
In [26]: row.BaR
Out[26]: 'asdf'
In [27]: row.bar
Out[27]: 'asdf'