Storm或SQLAlchemy ORM是否支持从现有数据库创建模式?

3 投票
1 回答
1022 浏览
提问于 2025-04-18 02:31

在讨论Storm这个Python的ORM(对象关系映射工具)时,我想自动生成一个MySQL数据库的结构。它的主页上说:

“Storm与现有的数据库结构配合得很好。”( https://storm.canonical.com/FrontPage),

所以我希望能不需要手动创建模型类。不过,‘入门’教程( https://storm.canonical.com/Tutorial)建议说,每个表都需要手动创建一个像下面这样的类,并且每个字段也得手动指定:

class Person(object):
  __storm_table__ = "person"
  id = Int(primary=True)
  name = Unicode()

另外,SQLAlchemy似乎也不支持反向工程的功能,但它需要像这样的结构:

user = Table('user', metadata,
  Column('user_id', Integer, primary_key = True),
  Column('user_name', String(16), nullable = False),
  Column('email_address', String(60)),
  Column('password', String(20), nullable = False)
)

当然,这些类和结构是有道理的,因为每个表可能代表某种“感兴趣的对象”,而且可以在这些类上扩展各种功能。不过,创建这些类的过程很繁琐,而且当数据库已经存在时,它们的(初始)内容其实是很简单的。

有一个ORM允许进行反向工程,链接是:

http://docs.doctrine-project.org/en/2.0.x/reference/tools.html

有没有类似的反向工程工具可以用于Storm、SQLAlchemy,或者其他Python的ORM,或者Python数据库的“美化工具”?

1 个回答

3

我不太清楚Storm是怎么处理这个过程的,但你可以用sqlalchemy来反映数据库中的表。比如,下面是一个我现在能访问的SQL Server实例的基本示例。

整个数据库

>>> from sqlalchemy import create_engine, MetaData
>>> engine = create_engine('mssql+pyodbc://<username>:<password>@<host>/<database>')  # replace <username> with user name etc.
>>> meta = MetaData()
>>> meta.reflect(bind=engine)
>>> funds_table = meta.tables['funds']  # tables are stored in meta.tables dict
>>> funds_table  # now stores database schema object
Table(u'funds', MetaData(bind=None), Column(u'fund_token', INTEGER(), table=<funds>, primary_key=True, nullable=False), Column(u'award_year_token', INTEGER(), ForeignKey(u'award_year_defn.award_year_token'), table=<funds>, nullable=False), ... Column(u'fin_aid_disclosure_category', VARCHAR(length=3, collation=u'SQL_Latin1_General_CP1_CI_AS'), table=<funds>), Column(u'report_as_additional_unsub', BIT(), table=<funds>, server_default=DefaultClause(<sqlalchemy.sql.expression.TextClause object at 0x000000000545B6D8>, for_update=False)), schema=None)

如果你只想一次反映一个表,可以用下面的代码。

一次一个表(速度更快)

>>> from sqlalchemy import Table, create_engine, MetaData
>>> engine = create_engine('mssql+pyodbc://<username>:<password>@<host>/<database>')
>>> meta = MetaData()
>>> funds_table = Table('funds', meta, autoload=True, autoload_with=engine)  # indicate table name (here 'funds') with a string passed to Table as the first argument
>>> funds_table  # now stores database schema object
Table(u'funds', MetaData(bind=None), Column(u'fund_token', INTEGER(), table=<funds>, primary_key=True, nullable=False), Column(u'award_year_token', INTEGER(), ForeignKey(u'award_year_defn.award_year_token'), table=<funds>, nullable=False), ... Column(u'fin_aid_disclosure_category', VARCHAR(length=3, collation=u'SQL_Latin1_General_CP1_CI_AS'), table=<funds>), Column(u'report_as_additional_unsub', BIT(), table=<funds>, server_default=DefaultClause(<sqlalchemy.sql.expression.TextClause object at 0x000000000545B6D8>, for_update=False)), schema=None)

你可能能想象到,这样你就可以保存相关表的数据,以便将来更快地访问这些表。

撰写回答