On 09/06/2016 09:50 AM, bsdz wrote:
Hi I am trying to implement optional tables with DeferredReflection. The idea is in different environments certain tables might exist while not in others. I have tried removing the tables from the metadata for the declarative base if the table's info doesn't list the environment (see below)
your code example claims to use some method "metadata.tables.remove(<table>)" but no such method exists.
but it
looks like the prepare() method doesn't take this metadata into account.
You might have a better experience with the automap extension, which covers this use case a little more completely, in that you can pass a pre-reflected "MetaData" object to prepare() which will just be applied based on what's in it. The MetaData you can set up using reflect(), which will only include the tables that are actually in that database.
Or, in this case DeferredReflection works based on subclasses of the given class you call prepare() on. So you could just use mixins:
class A(Prod, Dev, Base): # ... class B(Prod, Base): # ... Prod.prepare(engine) haven't tried that but seems like it should work here.
Here is stripped down version of what I am trying to do: | import sqlalchemy as sa from sqlalchemy.orm import sessionmaker, relationship from sqlalchemy.ext.declarative import declarative_base, DeferredReflection e = sa.create_engine("sqlite://", echo=True) e.execute(""" create table country ( country_id integer primary key ) """) Base = declarative_base(cls=DeferredReflection) # exists in PROD & DEV class Country(Base): __tablename__ = 'country' __table_args__ = ( {'info': { 'supported_envs': {'PROD', 'DEV'} } }) # exists only in PROD class User(Base): __tablename__ = 'user' __table_args__ = ( {'info': { 'supported_envs': {'PROD'} } }) country_id = sa.Column(sa.Integer, sa.ForeignKey('country.country_id')) country = relationship("Country", uselist=False) class MyModel(object): def __init__(self, env): self._engine = e for name, table in Base.metadata.tables.items(): if env not in table.info['supported_envs']: print "removing table '%s' from metadata as not in supported env" % name Base.metadata.remove(table) Base.metadata.bind = self._engine Base.prepare(self._engine) def create_session_maker(self): return sessionmaker(bind=self._engine) # This code is run in another module. mymodel = MyModel("DEV") Session = mymodel.create_session_maker() session = Session() | This has the following output: | 2016-09-06 14:43:21,674 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 2016-09-06 14:43:21,675 INFO sqlalchemy.engine.base.Engine () 2016-09-06 14:43:21,676 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 2016-09-06 14:43:21,677 INFO sqlalchemy.engine.base.Engine () 2016-09-06 14:43:21,678 INFO sqlalchemy.engine.base.Engine create table country ( country_id integer primary key ) 2016-09-06 14:43:21,679 INFO sqlalchemy.engine.base.Engine () 2016-09-06 14:43:21,680 INFO sqlalchemy.engine.base.Engine COMMIT removing table 'user' from metadata as not in supported env 2016-09-06 14:43:21,686 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("country") 2016-09-06 14:43:21,687 INFO sqlalchemy.engine.base.Engine () 2016-09-06 14:43:21,688 INFO sqlalchemy.engine.base.Engine PRAGMA foreign_key_list("country") 2016-09-06 14:43:21,688 INFO sqlalchemy.engine.base.Engine () 2016-09-06 14:43:21,689 INFO sqlalchemy.engine.base.Engine PRAGMA index_list("country") 2016-09-06 14:43:21,690 INFO sqlalchemy.engine.base.Engine () 2016-09-06 14:43:21,692 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("user") 2016-09-06 14:43:21,693 INFO sqlalchemy.engine.base.Engine () NoSuchTableError: user | Any suggestions on how to achieve this in SQL Alchemy? Thanks Blair -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com <mailto:sqlalchemy+unsubscr...@googlegroups.com>. To post to this group, send email to sqlalchemy@googlegroups.com <mailto:sqlalchemy@googlegroups.com>. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.
-- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.