自动从数据库架构创建类的Python ORM

2 投票
3 回答
1888 浏览
提问于 2025-04-16 02:45

有没有一个Python的ORM(对象关系映射)工具,可以根据给定的数据库结构自动生成Python类(生成代码,以便我可以扩展它们)?

我经常需要处理一些小任务,涉及不同的数据库(比如从各种来源导入/导出数据等),我觉得用Python配合这个工具会非常合适。

它应该像Visual Studio的ADO.NET/Linq for SQL设计器那样,我可以直接拖放数据库表,VS就会为我生成类……

提前谢谢你们。

3 个回答

0

我最近遇到了一个问题,发现这个问题和我碰到的情况很相似。

经过仔细阅读,我想用一种现代且非常实用的解决方案来更新答案,这个方案是由SQLAlchemy提供的——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'>
3

你并不需要把你的类写成源代码的样子才能扩展它们。

唯一需要注意的是,你需要在导入定义派生类的模块之前,让ORM生成这些类。

更好的方法是,不要使用继承,而是用 __getattr____setattr__ 来实现对ORM类的透明委托。

撰写回答