On 09/07/2016 05:08 AM, bsdz wrote:
No worries and thanks for the suggestions/advice so far.

Tbh I tried the mixin approach first as described in the docs but had
problems when trying to query anything on the 2nd class.

This is a boiled down version of what I tried:

the result doesn't make sense because it is querying Country just fine, then seems to think User is not a declarative class. This seems like you just have the wrong symbol being referred to somewhere (in an import or similar).

Here's a demo of what I had in mind:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection

e = create_engine("sqlite://", echo=True)
e.execute("""
    create table a (id integer primary key)
""")
e.execute("""
    create table b (id integer primary key)
""")

# note no 'c'


Base = declarative_base()


class Base(DeferredReflection, Base):
    __abstract__ = True


class Prod(Base):
    __abstract__ = True


class Dev(Base):
    __abstract__ = True


class A(Prod, Dev):
    __tablename__ = 'a'
    id = Column(Integer, primary_key=True)


class B(Prod, Dev):
    __tablename__ = 'b'
    id = Column(Integer, primary_key=True)


class C(Dev):
    __tablename__ = 'c'
    id = Column(Integer, primary_key=True)


Prod.prepare(e)


s = Session(e)
s.add_all([A(), B(), A(), B()])
s.commit()

print(s.query(A).all())
print(s.query(B).all())






|
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
     )
""")

e.execute("""
     create table user (
       user_id integer primary key
     )
""")

Base = declarative_base(cls=DeferredReflection)
Base2 = declarative_base(cls=DeferredReflection)

# exists in PROD & DEV
class Country(Base):
     __tablename__ = 'country'

# exists only in PROD
class User(Base2):
     __tablename__ = 'user'

     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

         # Base.metadata.bind = self._engine - binding at this level
didn't help :(

         if env == "DEV":
             Base2.metadata.bind = self._engine
             Base2.prepare(self._engine)

         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("PROD")
Session = mymodel.create_session_maker()
session = Session()

session.query(Country).count()
session.query(User).count()
|

And the result:

|

2016-09-07 10:03:43,889 INFO sqlalchemy.engine.base.Engine SELECT CAST('test 
plain returns' AS VARCHAR(60)) AS anon_1
2016-09-07 10:03:43,891 INFO sqlalchemy.engine.base.Engine ()
2016-09-07 10:03:43,892 INFO sqlalchemy.engine.base.Engine SELECT CAST('test 
unicode returns' AS VARCHAR(60)) AS anon_1
2016-09-07 10:03:43,893 INFO sqlalchemy.engine.base.Engine ()
2016-09-07 10:03:43,894 INFO sqlalchemy.engine.base.Engine
     create table country (
       country_id integer primary key
     )

2016-09-07 10:03:43,895 INFO sqlalchemy.engine.base.Engine ()
2016-09-07 10:03:43,896 INFO sqlalchemy.engine.base.Engine COMMIT
2016-09-07 10:03:43,897 INFO sqlalchemy.engine.base.Engine
     create table user (
       user_id integer primary key
     )

2016-09-07 10:03:43,897 INFO sqlalchemy.engine.base.Engine ()
2016-09-07 10:03:43,898 INFO sqlalchemy.engine.base.Engine COMMIT
2016-09-07 10:03:43,902 INFO sqlalchemy.engine.base.Engine PRAGMA 
table_info("country")
2016-09-07 10:03:43,903 INFO sqlalchemy.engine.base.Engine ()
2016-09-07 10:03:43,904 INFO sqlalchemy.engine.base.Engine PRAGMA 
foreign_key_list("country")
2016-09-07 10:03:43,905 INFO sqlalchemy.engine.base.Engine ()
2016-09-07 10:03:43,906 INFO sqlalchemy.engine.base.Engine PRAGMA 
index_list("country")
2016-09-07 10:03:43,906 INFO sqlalchemy.engine.base.Engine ()
2016-09-07 10:03:43,910 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2016-09-07 10:03:43,912 INFO sqlalchemy.engine.base.Engine SELECT count(*) AS 
count_1
FROM (SELECT country.country_id AS country_country_id
FROM country) AS anon_1
2016-09-07 10:03:43,912 INFO sqlalchemy.engine.base.Engine ()

InvalidRequestError: SQL expression, column, or mapped entity expected - got 
'<class '__main__.User'>'

|

I'm pretty sure I also tried the abstract approach with similar results.
Perhaps I'm binding incorrectly?

On Tuesday, 6 September 2016 18:37:14 UTC+1, Mike Bayer wrote:



    On 09/06/2016 12:50 PM, bsdz wrote:
    > Thanks for your reply.
    >
    > I think you misread my code. The method "remove" does exist. It's
    a method of MetaData and not tables. See
    
http://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData
    
<http://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html#sqlalchemy.schema.MetaData>.


    I did misread.

    >
    > I'm not sure about automap. I'm not keen on reflecting all the
    tables in my database and prefer fine grained control.


    metadata.reflect() allows for limiting the set of tables using "only":

    
http://docs.sqlalchemy.org/en/latest/core/metadata.html?highlight=metadata.reflect#sqlalchemy.schema.MetaData.reflect.params.only
    
<http://docs.sqlalchemy.org/en/latest/core/metadata.html?highlight=metadata.reflect#sqlalchemy.schema.MetaData.reflect.params.only>



     > Furthermore, I would like to keep deferred reflection as it allows
    one to choose an environment before binding to an engine.

    automap and deferred reflection kind of do the same thing, it's just
    the
    former does a lot more.

    in any case, launching prepare() from targeted mixins w/
    DeferredReflection should work if I'm reading the code correctly (which
    we've already demonstrated is challenging me today).




--
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.

Reply via email to