is there a python ORM (object relational mapper) that has a tool for automatically creating python classes (as code so I can expand them) from a given database schema?
I'm frequently faced with small tasks involving different databases (like importing/exporting from various sources etc.) and I thought python together with the abovementioned tool would be perfect for that.
It shoul开发者_StackOverflowd work like Visual Studios ADO.NET/Linq for SQL designer, where I can just drop DB tables and VS creates classes for me ...
Thanks in advance.
Django does this.
http://docs.djangoproject.com/en/1.2/howto/legacy-databases/#howto-legacy-databases
You do not need to produce a source code representation of your classes to be able to expand them.
The only trick is that you need the ORM to generate the classes BEFORE importing the module that defines the derived classes.
Even better, don't use derivation, but use __getattr__
and __setattr__
to implement transparent delegation to the ORM classes.
I recently found this question as I stumbled to the same problem.
And after more careful reading I would like to update the answers with this modern and very useful (IMHO) solution provided by SQLAlchemy - Automap https://docs.sqlalchemy.org/en/14/orm/extensions/automap.html
UPDATE (as suggested by rikyeah):
Suppose we want a table for clubs - id, names etc. We can make it hard way like this:
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)}')
Console:
>>>The type of Club class is <class 'sqlalchemy.orm.decl_api.DeclarativeMeta'>
But
if we have already this table in our DB we could just load it :
# 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)}')
And the console output is the same class:
>>>The type of ClubDB is <class 'sqlalchemy.orm.decl_api.DeclarativeMeta'>
精彩评论