SQLAlchemy核心 - 如何使ResultProxy不区分大小写的wrt Schema列名?

时间:2017-07-05 07:37:22

标签: python sqlalchemy database-schema

使用SQL Alchemy核心时,如何避免后端数据库之间列名更改的错误?我不控制后端,我不需要写入它们,我只想选择数据并查看值。

假设你有create table foo(bar int)。或类似的东西。在SQL Server中,它将是create table FOO(BAR int)

执行select * from FOO,这在Oracle,Postgres和MS Sqlserver中都可以正常工作。

但是,Postgres和Oracle将返回sqlalchemy.engine.result.RowProxy实例,我可以print(row.bar)

虽然SQL Server将使用完全相同的查询返回完全相同的数据,但我必须使用print(row.BAR)

现在,结果列表中的每个RowProxy都使用一个共享属性_keymap,它将字段名映射到_row属性中的位置,该属性包含查询为该数据库行返回的数据。

所以,给定一个_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时,抽象列上/下模式名称似乎是一个相当普遍的问题,这似乎非常有能力做到这一点。

我错过了什么吗?是不是有内置的方式?

这是使用原始SQL的SQL Alchemy,即我的应用程序将查询构建为纯SQL。我不能使用ORM,这完全超出了范围。我也无法调整数据库后端的配置以使用大写或小写名称 - 我无法控制它们。

1 个答案:

答案 0 :(得分:1)

您可能正在寻找

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'