首页 > 解决方案 > SQLAlchemy:如何多次创建动态列

问题描述

由于 python 类反射,我成功地创建了一个动态定义列的 sql 表。但是我不能多次运行代码。例如,下面的import_file应该创建一个静态表和一个具有特定列的动态表。如果我运行一次它就可以工作。但是第二次崩溃并返回以下错误:

Table 'dynamic' is already defined for this MetaData instance

代码示例:

from sqlalchemy import Column, Integer, String, Float, Boolean, Table
from sqlalchemy import create_engine, MetaData
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.orm import clear_mappers

import os

def import_file(filename, columns):
    path =  filename
    if os.path.exists(path):
        os.remove(path)

    engine = create_engine(f"sqlite:///{path}", echo=True)

    clear_mappers()
    Base = declarative_base()

    class StaticTable(Base):
        __tablename__ = "static"
        id = Column(Integer, primary_key=True)
        name = Column(String)


    class DynamicTable(Base):
        __tablename__ = "dynamic"
        id = Column(Integer, primary_key=True)

    for c in columns:
        setattr(DynamicTable,c,Column(String))

    Base.metadata.create_all(engine)


import_file("test.db", columns = ["age","test"]) # WORKS
import_file("test2.db", columns= ["id","age","foo","bar"]) # NOT WORKING

我尝试使用sqlalchemy.orm.clear_mappers,但没有成功。知道如何解决吗?

标签: pythonsqlalchemydatabase-metadata

解决方案


我认为你的代码并不完整,因为Base.metadata上的冲突

orm 类和表上的链接映射器,您已经定义了表。

你可以试试这样的想法

import_file("test.db", columns = ["age","test"])
Base.metadata.clear()
sqlalchemy.orm.clear_mappers()
import_file("test2.db", columns= ["id","age","foo","bar"])

推荐阅读