【问题标题】:SQLAlchemy core - how to make a ResultProxy case-insensitive wrt Schema column names?SQLAlchemy 核心 - 如何使 ResultProxy 不区分大小写的 wrt Schema 列名?
【发布时间】:2017-12-08 17:52:00
【问题描述】:

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

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

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

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

虽然 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) 而不想知道后端数据库是否存储 barBAR

但是,在针对多个数据库引擎使用 SQL Alchemy 时,抽象列上/下模式名称似乎是一个相当普遍的问题,一般来说它似乎非常胜任。

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

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

【问题讨论】:

    标签: python sqlalchemy database-schema


    【解决方案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'
    

    【讨论】:

    • 我应该记得检查 create_engine 选项,这就是这类东西所属的地方。我的回归测试表明它可以正常工作,无论如何,我所询问的基本用法与您的建议相得益彰。发送!
    • 这还在工作吗@Ilja Everilä ?case_sensitive 似乎已被弃用 -> docs.sqlalchemy.org/en/14/core/…
    • 看起来它正在消失,所以应用程序应该努力区分大小写。当然,如果尝试使相同的代码与多个 DBMS 一起工作,这可能是一个挑战。将不得不在某个时候重新审视这一点。
    猜你喜欢
    • 1970-01-01
    • 2017-09-14
    • 2017-09-02
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 2013-05-10
    • 2016-11-10
    • 1970-01-01
    相关资源
    最近更新 更多