SQLAlchemy是否可以将现有数据库表自动化为类,但是覆盖某些表的某些字段?
我正在腌制MetaData对象,因为它需要一些时间,它包含所有表,但是当我试图覆盖某些对象时,它会引发一个异常,即MetaData对象未绑定到Engine或Connection
from sqlalchemy.ext.automap import automap_base
from sqlalchemy import create_engine, MetaData, Column, String, Integer
import os, pickle
class MetadataCache(object):
def __init__(self, engine, schema):
self.engine = engine
self.schema = schema
self.metadata = None
@property
def cache_name(self):
final_name = '{0}.{1}.cache'.format(self.engine.url.database,
self.schema)
return final_name
def get_or_create_metadata(self):
if os.path.exists(self.cache_name):
with open(self.cache_name, 'r') as cachefile:
self.metadata = pickle.load(cachefile)
else:
self.metadata = MetaData()
self.metadata.reflect(bind=self.engine, schema=self.schema)
with open(self.cache_name, 'w') as cachefile:
pickle.dump(self.metadata, cachefile)
return self.metadata
engine = create_engine('...')
metadata = MetadataCache(engine, 'schemaname').get_or_create_metadata()
Base = automap_base(metadata=metadata)
class User(Base):
__tablename__ = 'user'
id = Column('id', Integer, primary_key=True)
name = Column('name', String)
class Profile(Base):
__tablename__ = 'profile'
id = Column('id', Integer, primary_key=True)
userid = Column('userid', ForeignKey('user.id'))
Base.prepare(reflect=True)
答案 0 :(得分:1)
引发错误是因为Base
拥有的元数据(您传递给automap_base
构造函数)没有绑定到引擎,也不应该绑定到引擎。这只是意味着你必须将绑定传递给Base.prepare
。
此外,由于您手动反映了元数据,因此您不应该告诉Base.prepare
这样做。
将最后一行更改为:
Base.prepare(engine)
编辑:当然,我在考虑Base.prepare
需要引擎进行反射,但是因为您正在通过预先反映的MetaData()
,你可以使用:
Base.prepare()
修改强>
在回复以下评论时,请注意您必须将extend_existing=True
传递给Table
:
class User(Base):
__tablename__ = 'user'
__table_args__ = {'extend_existing': True}
id = Column('id', Integer, primary_key=True)
name = Column('name', String)