首页 > 解决方案 > 如何在 SQLAlchemy 中为所有表全局设置“mysql_default_charset”和“mysql_collat​​e”,而不是使用“__table_args__”在每个表的基础上设置?

问题描述

我一直在为使用 SQLAlchemy 创建的 MySQL 中的表设置“字符集”和“排序规则”。

特别是,始终使用“latin1”为“字符集”和“排序规则”创建表。

在 URL 中设置“字符集”并没有解决问题:

f'mysql+pymysql://{_user}:{_pwd}@{_host}:{_port}/{_db}?charset=utf8mb4',

没有,没有create_engine(...,encoding='utf8')

只有通过设置以下__table_args__,才能创建支持 UTF-8 的表:

__table_args__ = (
    {'mysql_default_charset': 'utf8',
     'mysql_collate': 'utf8_bin'}
)

如何为数据库中的所有表设置上述表参数,而不必__table_args__为每个表显式指定它们?

完整示例

class Match(Base):
    __tablename__ = 'stash_match'

    id = Column(Integer, primary_key=True, autoincrement=True)
    blob_id = Column(String(40))
    text = Column(Text, nullable=False)
    regex = Column(Text, nullable=False)

    blob = relationship('Blob', back_populates='matches')

    __table_args__ = (
        ForeignKeyConstraint([blob_id], [Blob.id], onupdate='CASCADE', ondelete='CASCADE'),
        {'mysql_default_charset': 'utf8',
         'mysql_collate': 'utf8_bin'}
    )

标签: mysqlpython-3.xsqlalchemy

解决方案


如文档here中所述,您可以扩充声明性Base类以自定义默认行为:

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker

connection_uri = (
    "mysql+pymysql://root:toot@localhost:3307/mydb?charset=UTF8mb4"
)
engine = sa.create_engine(connection_uri, echo=True,)


class Base(object):
    __table_args__ = {
        "mysql_default_charset": "utf16",
        "mysql_collate": "utf16_icelandic_ci",
    }


Base = declarative_base(cls=Base)


class Team(Base):
    __tablename__ = "team"
    prov = sa.Column(sa.String(2), primary_key=True)
    city = sa.Column(sa.String(20), primary_key=True)
    team_name = sa.Column(sa.String(20))

    def __repr__(self):
        return f"<Team(prov='{self.prov}', city='{self.city}')>"


Base.metadata.create_all(engine)

被渲染的 DDL 是

CREATE TABLE team (
    prov VARCHAR(2) NOT NULL, 
    city VARCHAR(20) NOT NULL, 
    team_name VARCHAR(20), 
    PRIMARY KEY (prov, city)
)DEFAULT CHARSET=utf16 COLLATE utf16_icelandic_ci

推荐阅读