SQLAlchemy ORM 在插入时转换输入数据

Posted

技术标签:

【中文标题】SQLAlchemy ORM 在插入时转换输入数据【英文标题】:SQLAlchemy ORM to convert input data on insert 【发布时间】:2019-11-21 17:19:38 【问题描述】:

我想使用 SQLAlchemy ORM 将记录加载到 Postgres,但出现此错误: psycopg2.ProgrammingError:无法适应类型'lxml.objectify.StringElement'

我有模型:

class B2bProduct(Base):
    __tablename__ = 'b2b_product'
    code = Column(String, primary_key=True)

当我尝试插入产品列表时(值类型为'lxml.objectify.StringElement'的字典列表):

with session_scope() as s:
    s.bulk_insert_mappings(B2bProduct, prod_list)

我收到此错误:

psycopg2.ProgrammingError: can't adapt type 'lxml.objectify.StringElement'

作为一种解决方法,我可以在批量插入之前将所有值转换为 Python 字符串。但是,我更喜欢在 B2bProduct 类定义中进行强制转换。是否可以使用声明性 ORM,以便它会自动将我给它的任何值转换为 Python 字符串(在实际插入之前)?

类似这样的:

code = Column(String, primary_key=True, convert_to_string=True)

我不知道,但我可能会询问将进行转换的 TypeEngine。能给点建议吗?

【问题讨论】:

您可以使用自定义类型将您的 StringElement 调整为真正的字符串:docs.sqlalchemy.org/en/13/core/custom_types.html 我试过 ***.com/questions/32244211/… 但它似乎不适用于批量插入 这不是我建议的,使用自定义类型并阅读我发送给您的文档。 【参考方案1】:

所以我发现答案是 Raito 暗示的 TypeDecorator。谢谢。

class Float2(types.TypeDecorator):
    ''' Float Type that replaces commas with  dots on input '''
    impl = types.Float
    def process_bind_param(self, value, dialect):  # insert
        return value.replace(',','.')
    def process_result_value(self, value, dialect):  # select
        return value

【讨论】:

以上是关于SQLAlchemy ORM 在插入时转换输入数据的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy 将外连接 ORM 查询转换为 Core

ORM框架SQLAlchemy

sqlalchemy 使用pymysql连接mysql 1366错误

sqlalchemy 使用pymysql连接mysql 1366错误

SqlAlchemy ORM

ORM框架SQLAlchemy与权限管理系统的数据库设计