【问题标题】:Python ORM that automatically creates classes from DB schema自动从 DB 模式创建类的 Python ORM
【发布时间】:2011-03-29 13:43:06
【问题描述】:

是否有一个 python ORM(对象关系映射器)具有从给定数据库模式自动创建 python 类(作为代码以便我可以扩展它们)的工具?

我经常面临涉及不同数据库的小任务(例如从各种来源导入/导出等),我认为 python 和上述工具将非常适合。

它应该像用于 SQL 设计器的 Visual Studios ADO.NET/Linq 一样工作,我可以在其中删除 DB 表,而 VS 为我创建类...

提前致谢。

【问题讨论】:

    标签: python orm code-generation


    【解决方案1】:
    【解决方案2】:

    您无需生成类的源代码表示即可扩展它们。

    唯一的技巧是在导入定义派生类的模块之前,您需要 ORM 来生成类。

    更好的是,不要使用派生,而是使用__getattr____setattr__ 来实现对ORM 类的透明委托。

    【讨论】:

    • 感谢我非常喜欢的想法。对于这种方法,您建议使用哪种 ORM?我研究过的 ORM 要求我手动定义映射类(至少据我所知......)
    • 我只熟悉 SQLAlchemy,它确实有一个数据库自省工具 sqlalchemy.org/docs/reference/ext/sqlsoup.html>,但它似乎并不容易用于您的目的。
    【解决方案3】:

    我最近发现了这个问题,因为我偶然发现了同样的问题。

    在仔细阅读之后,我想用 SQLAlchemy 提供的这个现代且非常有用的 (IMHO) 解决方案来更新答案 - Automap https://docs.sqlalchemy.org/en/14/orm/extensions/automap.html

    更新(由rikyeah 建议):

    假设我们想要一个包含俱乐部的表格 - id、名称等。 我们可以这样做:

    from sqlalchemy import create_engine, ForeignKey
    from sqlalchemy import Column, Date, Integer, String, SmallInteger, MetaData
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.ext.automap import automap_base
    from settings import load_settings
    
    Base = declarative_base()
    
    # ORM object
    class Club(Base):
        __tablename__ = "club"
    
        id = Column(Integer, primary_key=True)
        native_name = Column(String)
        english_name = Column(String)
        country_code = Column(String)
        country_name = Column(String)
        current_league = Column(String)
    
        def __init__(self,
                     pk, native_name, english_name, country_code, country_name, current_league):
            self.id = pk
            self.native_name = native_name
            self.english_name = english_name
            self.country_code = country_code
            self.country_name = country_name
            self.current_league = current_league
    
    
    print(f'The type of Club class is {type(Club)}')
    

    控制台:

     >>>The type of Club class is <class 'sqlalchemy.orm.decl_api.DeclarativeMeta'>
    

    但是

    如果我们的数据库中已经有这个表,我们可以加载它:

    # let's try AutoMap!
    pg, sa_settings = load_settings()
    
    engine = create_engine(url=sa_settings['sql_uri']);
    metadata = MetaData()
    
    metadata.reflect(engine)
    
    Base = automap_base(metadata=metadata)
    Base.prepare()
    
    # The magic follows
    ClubDB = Base.classes.club
    print(f'The type of ClubDB is {type(ClubDB)}')
    

    和控制台输出是同一个类:

     >>>The type of ClubDB is <class 'sqlalchemy.orm.decl_api.DeclarativeMeta'>
    

    【讨论】:

    • @S.Lot 上面的 Django 链接也坏了
    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2016-05-17
    • 2010-11-02
    • 2016-02-10
    • 1970-01-01
    • 2011-10-28
    • 2011-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多