我正在使用 fastapi 为教育应用程序构建多语言 api。
我为翻译的部分创建了不同的表,并为不同的语言创建了 mysql 视图。
我不想为每个翻译的表部分编写不同的 pydantic 类。
相反,我编写了一些函数来操作 sqlalchemy 表的 _tablename_ 属性。通过这种方式,我认为我可以到达不同的表,例如 Lesson_en 或 Lesson_de,它们只是翻译部分的 mysql 视图。表结构和视图结构与原始 sqlalchemy 模型和 pydantic 模式相匹配。
例如
def get_table_suffix():
lang = sys_vars.CURRENT_LOCAL__LANG
print(str(lang) + "from get_table_suffix")
match lang:
case "":
return ""
case "en":
return "_en"
case "de":
return "_de"
def get_localized_table_name(tbl_nm: str):
table_name = tbl_nm + get_table_suffix()
return table_name
然后..
class LessonSummary(Base):
__tablename__ = get_localized_table_name("lessons")
用于匹配正确的语言视图 然后在登录功能中我调用..
settings: dict = get_user_settings(user)
set_user_lang(settings)
sys_vars.CURRENT_LOCAL__LANG = sys_vars.LOCAL_LANGUAGES[settings["language"]]
这些函数设置 CURRENT_LOCAL__LANG 会发生这种情况(我测试过) 但由于表已加载,更改表名不会更改表。
def get_user_settings(user: schemas.User):
settings: dict = {}
for setting in user.Settings:
settings[setting.SettingName] = setting.SettingValue
return settings
def set_user_lang(settings: dict):
sys_vars.CURRENT_LOCAL__LANG = sys_vars.LOCAL_LANGUAGES[settings["language"]]
print(sys_vars.CURRENT_LOCAL__LANG + " from set_user_lang")
return sys_vars.CURRENT_LOCAL__LANG
但是, _tablename_ 属性是在加载时设置的,我似乎无法在运行时更改它。 我尝试在应用程序加载路由器之前执行此操作,但用户登录发生在应用程序启动后,我需要访问表的实例。我尝试了 MetaData() obj 但没有运气
所以,我的问题.. 我在这个问题上走错了路吗? 我可以在运行时动态更改 _tablename_ 并反映会话中的更改吗? 我需要以某种方式重新加载吗? 我确实设法在 jwt 中正确存储语言,但无法更改表名。 那么如何在运行时更改它呢?
我尝试动态更改表名,但由于应用程序已经加载,所以我没有成功。
您可以使用这种方法:
def create_models():
localized_table_name = get_localized_table_name("lessons")
class LessonSummary(Base):
__tablename__ = localized_table_name
create_models()
engine = create_engine('sqlite://')
Base.metadata.create_all(bind=engine)