这是一个非常有趣的问题...... 我正在编写一个程序来通过SQLAlchemy操作具有相同模式的多个远程数据库。连接字符串不是静态的 - 它存储在本地SQLite数据库中。 我需要在运行时创建一个会话,并使用该会话来反映数据库架构。所有数据库都有相同的架构 我已经知道了表名。 无论如何要实现这个?
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)
编辑:最后我自己解决了这个问题:
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
然而,@ Gary van der Merwe的答案非常酷!
答案 0 :(得分:3)
您必须手动将orm类映射到反射表。
假设数据库具有以下结构:
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)
)
你可以这样做:
#!/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())