Reputation: 1171
Here's a pretty interesting question... I'm writing a program to manipulate several remote databases with same schema via SQLAlchemy. The connection string is not static -- it is stored in a local SQLite database. I need to create a session at runtime, and use that session to reflect the database schema. All databases have same schema. I have already know the table names. Anyway to implement this?
def connect(connstr):
engine = create_engine(connstr)
metadata = MetaData(bind=engine)
session = create_session(bind=engine)
return session
class User(Base):
# How it's possible to create a dummy model class without predefined metadata?
__table__ = Table('users', metadata, autoload=True)
EDIT: finally I solved this problem by myself:
Base = declarative_base()
def connect(connstr):
engine = create_engine(connstr)
metadata = MetaData(bind=engine)
session = create_session(bind=engine)
return metadata, session
def get_model(metadata, modelname, tablename):
cls = type(modelname, (Base,), dict(
__table__ = Table(tablename, metadata, autoload = True)
))
return cls
However, @Gary van der Merwe's answer is pretty cool!
Upvotes: 2
Views: 1552
Reputation: 9533
You have to manually map the orm classes to the reflected tables.
Assuming a database with the following structure:
CREATE TABLE "group" (
id INTEGER NOT NULL,
name VARCHAR(50),
PRIMARY KEY (id)
)
CREATE TABLE user (
id INTEGER NOT NULL,
name VARCHAR(50),
password VARCHAR(12),
group_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(group_id) REFERENCES "group" (id)
)
you can do:
#!/usr/bin/env python
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import mapper, Session, relationship
class Group(object):
def __init__(self, name):
self.name = name
class User(object):
def __init__(self, name, password, group):
self.name = name
self.password = password
self.group = group
group = relationship(Group)
def connect(url):
engine = create_engine(url, echo=True)
metadata = MetaData(engine, reflect=True)
# Do this for each table
mapper(User, metadata.tables['group'])
mapper(Group, metadata.tables['user'])
session = Session(bind=engine)
return session
session = connect('sqlite:///test.db')
finance_group = Group('finance')
session.add(finance_group)
session.add(User('joe', 'password', finance_group))
session.commit()
print(session.query(User).all())
Upvotes: 3