سؤال

ولقد قاعدة بيانات موجودة بالفعل وتريد الوصول إليه باستخدام SQLAlchemy. لأنه، هو تمكن بنية قاعدة البيانات عن طريق قطعة أخرى من التعليمات البرمجية (جانغو مكتب إدارة السجلات، في الواقع)، وأنا لا أريد أن أكرر نفسي، واصفا كل بنية الجدول، أنا باستخدام autoload التأمل. أنا عالقة مع الميراث الجدول ملموس بسيط.

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

وهنا هو رمز، مع طاولة descritions SQL كما جمل التوثيق:

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}

والجداول الفعلية لها أعمدة إضافية، ولكن هذا لا يهم تماما على السؤال، وذلك في محاولة للحد من رمز لقد تبسيط كل شيء فقط حتى النخاع.

والمشكلة هي، عند تشغيل هذا:

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

ووSQL الناتج هو معنى (لاحظ عدم وجود انضمام 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

وعندما أحاول الوصول إلى 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 (لقد omited الطبقة User وعلق الخط) تماما، لذلك يعمل FK التأمل.

وكيف يمكنني تنفيذ استعلام بسيط على القيم FooPayment والوصول Payment من الناتج مثلا؟

وأنا باستخدام SQLAlchemy 0.5.3، كيو 8.3، psycopg2 وبايثون 2.5.2. شكرا لأي اقتراحات.

هل كانت مفيدة؟

المحلول

وبنية الجدول الخاصة بك هي على غرار ما يستخدم في الميراث الجدول المشترك، لكنها بالتأكيد لا تتوافق مع الميراث الجدول ملموس حيث تتكرر كل المجالات من الفئة الأصل في جدول فرعية. الآن لديك فئة فرعية مع الحقول أقل من الأم وإشارة إلى مثيل الفئة الأصل. التبديل إلى الميراث الجدول المشترك (واستخدام FooPayment.amount في حالتك أو التخلي عن الميراث لصالح التجميع البسيط (المرجع).

والفلترة من حقل في نموذج آخر لا تضاف تلقائيا الانضمام الشرط. على الرغم من أنه من الواضح ما حالة ينبغي أن تستخدم في الانضمام على سبيل المثال، فمن غير الممكن تحديد هذه الحالة بشكل عام. هذا هو السبب لديك لتحديد الملكية يتعلق اشارة الى الدفع واستخدام أسلوب has() في مرشح للحصول السليم شرط الربط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top