SQLAlchemy自动化数据并覆盖一些列

Mar*_*ark 6 python sqlalchemy

在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)
Run Code Online (Sandbox Code Playgroud)

Raz*_*erM 4

引发错误的原因是Base(传递给automap_base构造函数的)拥有的元数据未绑定到引擎,也不应该绑定到引擎。这只是意味着您必须将绑定传递给Base.prepare.

另外,由于您是手动反映元数据,因此您不应该告诉您Base.prepare这样做。

将最后一行更改为:

Base.prepare(engine)
Run Code Online (Sandbox Code Playgroud)

编辑:当然,我正在考虑Base.prepare需要引擎来进行反射,但是由于您传递的是预反射MetaData(),因此您可以使用:

Base.prepare()
Run Code Online (Sandbox Code Playgroud)

编辑:

在回复下面的评论时,请注意您必须传递extend_existing=TrueTable

class User(Base):
    __tablename__ = 'user'
    __table_args__ = {'extend_existing': True}

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String)
Run Code Online (Sandbox Code Playgroud)