2012-06-27 13 views
6

SQLAlchemy'de birincil anahtar olmayan bir tablo oluşturmak mümkün mü? aşağıdaki gibi ben tanımlamak istediğiniz ilişkidir: Gördüğünüz gibiSQLAlchemy Birincil anahtar olan alt tablo olmadan bire çok

class TPost(Base): 
    __tablename__ = "forum_post" 
    id = Column(Integer, primary_key = True) 
    topic_id = Column(Integer, ForeignKey("forum_topic.id")) 
    index = Column(Integer) 
    page = Column(Integer) 
    user_id = Column(Integer, ForeignKey("forum_user.id")) 
    posted_at = Column(DateTime) 
    post_text = Column(String) 
    has_quotes = Column(Boolean) 
    quotes = relationship("TQuote") 

class TQuote(Base): 
    __tablename__ = "forum_quotes" 
    id = Column(Integer, ForeignKey("forum_post.id")) 
    is_direct = Column(Boolean) 
    quoted_text = Column(String) 
    quoted_id = Column(Integer) 

Gerçekten bir birincil anahtar gerekmez, ve gelecekte Quote ilişkiyi uzatmak niyetinde değiliz.

özellikle bu hata mesajı ile temsil edilmektedir Benim sorun:

sqlalchemy.exc.ArgumentError: Mapper Mapper|TQuote|forum_quotes 
could not assemble any primary key columns for mapped table 'forum_quotes' 

düzenleme: alıntı doğrudan değil ancak ne zaman (id,quoted_id) çifti benzersizdir ve verilerin çoğunluğu için mevcut (ve bu durumda bir quoted_id yoktur), alıntı metnini doğrudan alıntı ilişkisine dahil ettim. İkili bir tablo yaklaşımı kullanabilirim (buradaki doğru tırnaklar birincil anahtarlı bir tabloya sahiptir), ancak bunu gerçekten bire-bir ilişki olarak kullanmayı tercih ediyorum. Tek bir katılımdan daha fazlasını yapmak istemiyorum.

düzenlemek 2:

Ben tırnak numara ve bir pkey hala rahatsız edici tho olarak yabancı anahtar app oluşturulan numarayı kullanacağız. Şimdi sözdizimini anlamak için.

düzenlemek 3: yüksek bir seviyede veri modelleme yaparken bile relatioship uygulamak için ihtiyaç duyduğu tüm bilgiler beri sql simya ile oldukça rahatsız düzenlemek 2. özetlendiği gibi

sorunu çözüldü. Sql Alchemy'nin birincil bir anahtara sahip olmasını istediği nedenleri anlıyorum (orm, uygulamayı kolaylaştırır).

Sql Simya'yı neden kullanmam gerektiğini sorgulamaya başlıyorum, onsuz psycopg2'yi kullanarak tek yönlü UPSERT veya CREATE_IF_NOT_EXIST asenkron işlemlerini uygulayabiliyorum. ORM'nin gerçekten yakalanması gerekiyor.

+2

Neden birini kullanarak direnmeye çalışıyorsunuz? büyüklük mü? Veri modelinin temizliği? diğer sebep? – van

+0

Öncelikle temizlik. Ama eğer bir düşünceyi arttırdığınızı düşünüyorsanız, başka bir veritabanı operasyonu. –

+0

Evet, ancak bir PK tanımlamıyor olsanız bile, veritabanı hala bir dahili olarak kalır ve aynı artış işlemini gerçekleştirir.PK'lerin kullanımı tüm RDBMS'lerde gerçekten çok iyi optimize edilmiştir. Google, "birincil anahtarları temsil et" için, ve PK'ye sahip olmanın (buna ihtiyacınız olmasa bile) RDB'leri modellemenin en basit yolu olduğu sonucuna varabilirsiniz. Ama en önemlisi, sahip olmamanızdan tasarruf edeceğiniz hiçbir şey yoktur. Performans nedenleriyle, çoğunlukla (id, quoted_id) üzerinde arama yapıyorsanız, CLUSTED dizinini PK sütununun yerine (id, quoted_id) sütunlar olarak tanımlamak isteyebilirsiniz. – van

cevap

1

tırnak işaretleri, indeks vermek için ek bir sütun ekleyin ve sonra bu yeni sütuna + yabancı anahtarın bir kompozit anahtar yapmak ekleyin.

+0

teşekkürler – van

13

@TokenMacGuy'un doğru olduğunu ve PrimaryKey ve surrogate key kavramlarının kafa karıştırıcı olduğunu kabul ediyorum. Hangi durumda sorunuzun cevabı:

  • HAYIR, SA anahtar
  • ve HAYIR, oluşturmak birincil gerekmez bir olmadan tabloları (ve tablolara dolayısıyla ilişkileri) desteklemez primary key olarak hizmet vermek amacıyla her tablo için bir vekil anahtarı. Benzersiz bir sütun kombinasyonunu kullanarak bir PK tanımlayabilirsiniz.

Örnek için aşağıdaki kodu bakınız:

class TPost(Base): 
    __tablename__ = 'forum_post' 
    id = Column(Integer, primary_key = True) 
    post_text = Column(String) 
    quotes = relationship("TQuote", backref="post") 

class TQuote(Base): 
    __tablename__ = "forum_quotes" 
    id = Column(Integer, ForeignKey("forum_post.id")) 
    is_direct = Column(Boolean) 
    quoted_text = Column(String) 
    quoted_id = Column(Integer) 
    __table_args__ = (PrimaryKeyConstraint(id, quoted_id),) 
+0

Yanıtladığınız için teşekkür ederiz ve + 1'ledim. '(id, quoted_id)' = eğer id_direct = true ise sadece aday (adayların% 75'i bu kategoriye girer). Yani, tüm veriler için bir aday anahtarı olması için yeni bir alan kullanıyorum + 'id' yeni alan uygulama tarafından oluşturulan bir sayıdır. Gönderinizi güncelleyin ve <3 –

+1

kabul edeceğim. Soruyu sorulduğu gibi yanıtladım ve nasıl geliştirebileceğimi görmüyorum. Sorunu nasıl çözdüğünüze ilişkin ek bir yorum (bunu gönderdiğiniz) ile kabul etmek (veya vermemek) konusunda özgürsünüz. Ya da kendi çözümünüzü ekleyebilir ve bütünlük için kabul edebilirsiniz. Çözümünüzü paylaştığınız için – van

İlgili konular