强制 sqlalchemy 中的 insert 语句在所有列周围使用引号

Force insert statement in sqlalchemy to use quotes around all columns

提问人:Scott Boston 提问时间:11/15/2023 更新时间:11/16/2023 访问量:33

问:

使用 ORM 进行插入时,sqlalchemy 中是否有可以强制 python 库引用所有列的参数?

例如

INSERT INTO DATABASE_A.SCHEMA_A.TABLE_A (date, col1, "col 2") values (:data1, :data2, :data3)

是当前生成的语句,如果我使用带有列的 pandas 数据帧,并且 。请注意,由于空格,已引用。但是,我想继续引用,因为在我的数据库中,日期是一个保留字,需要引用。datecol1col 2col 2datecol1

是否有引擎或方言参数可以启用所有列的引号,以便生成的插入语句将导致:

INSERT INTO DATABASE_A.SCHEMA_A.TABLE_A ("date", "col1", "col 2") values (:data1, :data2, :data3)
蟒蛇 SQL炼金术

评论


答:

2赞 snakecharmerb 11/15/2023 #1

如果未引用保留字,则这是方言中的错误,应予以修复。在修复之前,在大多数情况下,方言的保留字可以像这样扩展*:

import sqlalchemy as sa

engine = sa.create_engine(url)
engine.dialect.preparer.reserved_words.add('date')

如果你真的想引用所有列名,你可以使用自定义编译

import sqlalchemy as sa
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.schema import CreateColumn
from sqlalchemy.sql.elements import quoted_name

@compiles(CreateColumn)
def my_column(element, compiler, **kw):
    column = element.element
    if not isinstance(column.name, quoted_name) or column.name.quote is None:
        column.name = quoted_name(column.name, True)
    return compiler.visit_create_column(element, **kw)

最后,对于 invidual 列,您可以传递给构造函数,quote=True

tbl = sa.Table(
          't', 
          sa.MetaData(), 
          sa.Column('c', sa.Date, quote=True)
)

但这种方法无法扩展,并假设您可以控制列定义,而使用 Pandas 或类似工具时可能并非如此。


* MySQL 和 MariaDB 在 SQLAlchemy 中具有单独的保留字集;如果使用 MariaDB,您可能需要通过添加 to 来查找和扩展 MariaDB 保留字集。sqlalchemy.dialects.mysql.reserved_words. RESERVED_WORDS_MARIADB