4
在SQLAlchemy中可以將現有數據庫表自動映射到類中,但是會覆蓋某些表的某些字段嗎?我正在酸洗MetaData對象,因爲它需要一些時間,它包含所有表格,但是當我試圖重寫某些對象時,它引發了一個異常,即MetaData對象未綁定到引擎或連接。提高SQLAlchemy自動映射數據並覆蓋一些列
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)
問題,至少據我所知,是我們想用剛醃製的元數據,而不引擎(最初用於創建元數據)必須可用(可能因爲數據庫不可用)。你能想到一個解決方法,可以做到這一點? – jcrudy
事實上,我已經混淆了思考答案,引擎不需要傳遞給'Base.prepare',我會編輯答案。 – RazerM
問題中的示例實際上並不是自包含的,因此我在此處創建了一個自包含的版本:https://gist.github.com/jcrudy/fb30f079dfcf29fc6e3bd97b037eee1a。當我運行它(將你的建議更改爲最後一行)時,我得到sqlalchemy.exc.InvalidRequestError:表'user'已經爲此MetaData實例定義。指定'extend_existing = True'來重新定義現有Table對象上的選項和列。實際上,錯誤發生在用戶類的定義上。 – jcrudy