There's a complete example of mapping to inherits "partitions" at https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/PostgreSQLInheritance. The key strategy here is that Postgresql handles the presence of the "inherits" tables implicitly, e.g. your "b" here. The ORM never knows about them. So it would only INSERT into "a".
Now in this case, your example is quite different. You are trying to add new columns to "b" that aren't in "a", and the way the above works, that would not be possible. When I wrote the "parititioning" document above, I vaguely recall reading that Postgresqls' inheritance feature was intended for the above use case alone. However these days, PG is pushing hard on the so-called "object oriented database" concept for some reason (IMO PG would benefit tremendously if they focused on out of the box HA instead of adding more and more SQL complexity, but here we are), so now their docs seem to encourage deep creativity with the inherits feature. Since your "b" table has every column you need, you would need to map it as "concrete=True". Then the "B" mapper will only deal with the "b" table and never refer to the "a" table. However, I'm not sure how well this works in terms of selecting from "A", if the polymorphic loading still works in that case or not, because the mapper might be expecting a separate "polymorphic selectable". But you should try adding the "concrete=True" example to the B mapping options and see if it works. If not, it might not be possible but I can try running an MCVE here to see what might be needed. As a separate issue, I'd also advise dropping the "public" schema from the mapping and instead ensuring your connection's search_path is set to "public", especially when doing reflection across schemas, see http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#remote-schema-table-introspection-and-postgresql-search-path for that. On Tue, May 22, 2018 at 1:17 PM, Demitri Muna <demitri.m...@gmail.com> wrote: > > Hello, > > I have two tables in PostgreSQL where one is INHERITed from the other: > > CREATE TABLE a > ( > pk serial, > type_pk integer, > value numeric, > CONSTRAINT a_pkey PRIMARY KEY (pk), > CONSTRAINT a_type_fk FOREIGN KEY (a_type_pk) > REFERENCES a_type (pk) MATCH SIMPLE > ON UPDATE CASCADE > ON DELETE RESTRICT > ); > > > CREATE TABLE type > ( > pk serial, > label text > ); > > > CREATE TABLE b > ( > pk , > type_pk , > value , > b_value numeric > ) > INHERITS (a); > > I have my SQLAlchemy classes defined like this: > > class Type(Base): > __tablename__ = 'a_type' > __table_args__ = {'autoload':True, 'schema':'public'} > > > class A(Base): > __tablename__ = 'a' > __table_args__ = {'autoload':True, 'schema':'public'} > > > type_pk = Column("type_pk", Integer, ForeignKey(Type.pk)) > > > type = relationship(Type, > primaryjoin=Type.pk==type_pk, > backref="as") > > > __mapper_args__ = { > 'polymorphic_identity':"a", > 'polymorphic_on':case([ > (type_pk == 1, "b") > ], else_="a") > } > > class B(A): > __tablename__ = 'b' > __table_args__ = {'autoload':True, 'schema':'public'} > > > pk = Column(name='pk', type_=Integer, primary_key=True, > autoincrement=True) > __mapper_args__ = { > 'polymorphic_identity': "b", > 'inherit_condition':pk==A.pk, > 'inherit_foreign_keys':['type_pk'] > } > > > > This very nearly works and I get the polymorphism I am looking for. When I > create a new B() object in code and look at the SQL generated, it triggers > two inserts - one for the 'a' table, and one for the 'b' table. How can I > suppress the INSERT into 'a'? With PostgreSQL's INHERIT, I only need the 'b' > INSERT. This works very well otherwise. > > I get a few of these warnings. Is there a configuration I need to specify to > tell SQLAlchemy not to worry about it? > >> >> /usr/local/anaconda/lib/python3.6/site-packages/sqlalchemy/orm/mapper.py:1766: >> SAWarning: Implicitly combining column a.pk with column b.pk under attribute >> 'pk'. Please configure one or more attributes for these same-named columns >> explicitly. > > > Finally, is there a way I can automatically set a default value of 1 for the > 'type_pk' propoerty when a new B() is created? I don't know if I can do this > in PostgreSQL since the field is inherited. > > Thanks! > > Demitri > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > description. > --- > 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. -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- 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.