Frage

Ich habe eine bereits existierende Datenbank und darauf zugreifen möchten mit SQLAlchemy.Da die Struktur der Datenbank ist verwaltet von einem anderen Teil des Codes (Django ORM, tatsächlich) und ich will nicht, mich zu wiederholen, beschreiben jede Tabelle Struktur, die ich verwende autoload Introspektion.Ich bin stecken mit einem einfachen konkrete Tabelle Vererbung.

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

Hier ist der code, table-SQL-descritions als 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}

Die aktuellen Tabellen haben zusätzliche Spalten, aber das ist völlig irrelevant für die Frage, so in Versuch zur Minimierung der code, den ich habe vereinfachte alles nur um die core.

Das problem ist, wenn ich dies ausführen:

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

Die resultierende SQL bedeutungslos ist (beachten Sie das fehlen von join condidion):

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

Und wenn ich versuche, auf payment.date Ich bekomme die folgende Fehlermeldung: Concrete Mapper|FooPayment|payments_foo does not implement attribute u'date' at the instance level.

Ich habe versucht, indem implizite foreign key reference id = Column('payment_ptr_id', Integer, ForeignKey('payments_payment.id'), primary_key=True) zu FooPayment ohne Erfolg.Versuchen print session.query(Payment).first().user Werke (habe ich weggelassen User Klasse und kommentiert die Zeile) perfekt, so dass FK Introspektion funktioniert.

Wie kann ich eine einfache Abfrage auszuführen, die auf FooPayment und Zugriff Payment's Werte aus der resultierenden Instanz?

Ich verwende SQLAlchemy 0.5.3, PostgreSQL 8.3, psycopg2 und Python 2.5.2.Vielen Dank für alle Vorschläge.

War es hilfreich?

Lösung

Ihre Tabellen-Strukturen sind ähnlich zu dem, was ist verwendet in die gemeinsame Tabelle Vererbung, aber Sie sind sicherlich nicht entsprechen, konkrete Tabelle Vererbung, wo alle Felder der übergeordneten Klasse sind doppelt in der Tabelle der Subklasse.Jetzt müssen Sie eine Unterklasse mit weniger Felder als die Muttergesellschaft und eine Referenz auf die Instanz der übergeordneten Klasse.Wechseln zu gemeinsamen Tabelle Vererbung (und FooPayment.amount in Ihrem Zustand oder geben, mit Vererbung zu Gunsten von einfache aggregation (Referenz).

Filter von einem Feld in ein anderes Modell hinzufügen nicht automatisch join-Bedingung.Obwohl es offensichtlich ist, in welchem Zustand sollten verwendet werden, verbinden Sie für Ihr Beispiel ist es nicht möglich zu bestimmen, eine solche Bedingung im Allgemeinen.Das ist, warum Sie haben, um zu definieren, Bezug Eigenschaft unter Bezugnahme auf die Zahlung und zur Verwendung der has() Methode im filter, um die richtige join-Bedingung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top