SQLAlchemy declarative concrete inheritance autoload table

I have an existing database and want to access it using SQLAlchemy. Since the database structure is controlled by another piece of code (Django ORM, actually), and I don't want to repeat myself describing each table structure, I use introspection autoload. I am stuck with simple inheritance of a specific table.

Payment                FooPayment
  + id (PK) <----FK------+ payment_ptr_id (PK)
  + user_id              + foo
  + amount
  + date

Here is the code with tabular SQL descriptions as docstrings:

class Payment(Base):
    """
    CREATE TABLE payments(
      id serial NOT NULL,
      user_id integer NOT NULL,
      amount numeric(11,2) NOT NULL,
      date timestamp with time zone NOT NULL,
      CONSTRAINT payment_pkey PRIMARY KEY (id),
      CONSTRAINT payment_user_id_fkey FOREIGN KEY (user_id)
          REFERENCES users (id) MATCH SIMPLE)
    """
    __tablename__ = 'payments'
    __table_args__ = {'autoload': True}
    # user = relation(User)

class FooPayment(Payment):
    """
    CREATE TABLE payments_foo(
      payment_ptr_id integer NOT NULL,
      foo integer NOT NULL,
      CONSTRAINT payments_foo_pkey PRIMARY KEY (payment_ptr_id),
      CONSTRAINT payments_foo_payment_ptr_id_fkey
          FOREIGN KEY (payment_ptr_id)
          REFERENCES payments (id) MATCH SIMPLE)
    """
    __tablename__ = 'payments_foo'
    __table_args__ = {'autoload': True}
    __mapper_args__ = {'concrete': True}

There are additional columns in real tables, but this is completely irrelevant to the question, therefore, trying to minimize the code, I simplified everything only to the kernel.

The problem is when I run this:

payment = session.query(FooPayment).filter(Payment.amount >= 200.0).first()
print payment.date

The resulting SQL does not make sense (note the lack of a join condition):

SELECT payments_foo.payment_ptr_id AS payments_foo_payment_ptr_id,
       ... /* More `payments_foo' columns and NO columns from `payments' */
    FROM payments_foo, payments
    WHERE payments.amount >= 200.0 LIMIT 1 OFFSET 0

payment.date, : Concrete Mapper|FooPayment|payments_foo does not implement attribute u'date' at the instance level.

id = Column('payment_ptr_id', Integer, ForeignKey('payments_payment.id'), primary_key=True) FooPayment - . print session.query(Payment).first().user ( User ) , Fros- .

FooPayment Payment ?

SQLAlchemy 0.5.3, PostgreSQL 8.3, psycopg2 Python 2.5.2. .

+3
1

, , , , , . , , . ( FooPayment.amount ().

. , , . , , has() .

+4

Source: https://habr.com/ru/post/1721230/


All Articles