2016-03-22 15 views
0

'da bir birleşik yük sql_query oluştururken anahtar isimlendirmeyi koru SQLAlchemy yoluyla başvurulan tüm tablolardan bir tablo satırı ve karşılık gelen satırı ayırım.SQLAlchemy

class DNAExtractionProtocol(Base): 
    __tablename__ = 'dna_extraction_protocols' 
    id = Column(Integer, primary_key=True) 
    code = Column(String, unique=True) 
    name = Column(String) 
    sample_mass = Column(Float) 
    mass_unit_id = Column(String, ForeignKey('measurement_units.id')) 
    mass_unit = relationship("MeasurementUnit", foreign_keys=[mass_unit_id]) 
    digestion_buffer_id = Column(String, ForeignKey("solutions.id")) 
    digestion_buffer = relationship("Solution", foreign_keys=[digestion_buffer_id]) 
    digestion_buffer_volume = Column(Float) 
    digestion_id = Column(Integer, ForeignKey("incubations.id")) 
    digestion = relationship("Incubation", foreign_keys=[digestion_id]) 
    lysis_buffer_id = Column(String, ForeignKey("solutions.id")) 
    lysis_buffer = relationship("Solution", foreign_keys=[lysis_buffer_id]) 
    lysis_buffer_volume = Column(Float) 
    lysis_id = Column(Integer, ForeignKey("incubations.id")) 
    lysis = relationship("Incubation", foreign_keys=[lysis_id]) 
    proteinase_id = Column(String, ForeignKey("solutions.id")) 
    proteinase = relationship("Solution", foreign_keys=[proteinase_id]) 
    proteinase_volume = Column(Float) 
    inactivation_id = Column(Integer, ForeignKey("incubations.id")) 
    inactivation = relationship("Incubation", foreign_keys=[inactivation_id]) 
    cooling_id = Column(Integer, ForeignKey("incubations.id")) 
    cooling = relationship("Incubation", foreign_keys=[cooling_id]) 
    centrifugation_id = Column(Integer, ForeignKey("incubations.id")) 
    centrifugation = relationship("Incubation", foreign_keys=[centrifugation_id]) 

    volume_unit_id = Column(String, ForeignKey('measurement_units.id')) 
    volume_unit = relationship("MeasurementUnit", foreign_keys=[volume_unit_id]) 

kullanıyorum: Aşağıdaki nesne yapısı göz önüne alındığında

sql_query = session.query(DNAExtractionProtocol).options(Load(DNAExtractionProtocol).joinedload("*")).filter(DNAExtractionProtocol.code == code) 
for item in sql_query: 
    pass 
mystring = str(sql_query) 
mydf = pd.read_sql_query(mystring,engine,params=[code]) 
print(mydf.columns) 

Bu bana verir: Bu gerçekten tek istediğim sütun içerir

Index([u'dna_extraction_protocols_id', u'dna_extraction_protocols_code', 
     u'dna_extraction_protocols_name', 
     u'dna_extraction_protocols_sample_mass', 
     u'dna_extraction_protocols_mass_unit_id', 
     u'dna_extraction_protocols_digestion_buffer_id', 
     u'dna_extraction_protocols_digestion_buffer_volume', 
     u'dna_extraction_protocols_digestion_id', 
     u'dna_extraction_protocols_lysis_buffer_id', 
     u'dna_extraction_protocols_lysis_buffer_volume', 
     u'dna_extraction_protocols_lysis_id', 
     u'dna_extraction_protocols_proteinase_id', 
     u'dna_extraction_protocols_proteinase_volume', 
     u'dna_extraction_protocols_inactivation_id', 
     u'dna_extraction_protocols_cooling_id', 
     u'dna_extraction_protocols_centrifugation_id', 
     u'dna_extraction_protocols_volume_unit_id', u'measurement_units_1_id', 
     u'measurement_units_1_code', u'measurement_units_1_long_name', 
     u'measurement_units_1_siunitx', u'solutions_1_id', u'solutions_1_code', 
     u'solutions_1_name', u'solutions_1_supplier', 
     u'solutions_1_supplier_id', u'incubations_1_id', u'incubations_1_speed', 
     u'incubations_1_duration', u'incubations_1_temperature', 
     u'incubations_1_movement', u'incubations_1_speed_unit_id', 
     u'incubations_1_duration_unit_id', u'incubations_1_temperature_unit_id', 
     u'solutions_2_id', u'solutions_2_code', u'solutions_2_name', 
     u'solutions_2_supplier', u'solutions_2_supplier_id', 
     u'incubations_2_id', u'incubations_2_speed', u'incubations_2_duration', 
     u'incubations_2_temperature', u'incubations_2_movement', 
     u'incubations_2_speed_unit_id', u'incubations_2_duration_unit_id', 
     u'incubations_2_temperature_unit_id', u'solutions_3_id', 
     u'solutions_3_code', u'solutions_3_name', u'solutions_3_supplier', 
     u'solutions_3_supplier_id', u'incubations_3_id', u'incubations_3_speed', 
     u'incubations_3_duration', u'incubations_3_temperature', 
     u'incubations_3_movement', u'incubations_3_speed_unit_id', 
     u'incubations_3_duration_unit_id', u'incubations_3_temperature_unit_id', 
     u'incubations_4_id', u'incubations_4_speed', u'incubations_4_duration', 
     u'incubations_4_temperature', u'incubations_4_movement', 
     u'incubations_4_speed_unit_id', u'incubations_4_duration_unit_id', 
     u'incubations_4_temperature_unit_id', u'incubations_5_id', 
     u'incubations_5_speed', u'incubations_5_duration', 
     u'incubations_5_temperature', u'incubations_5_movement', 
     u'incubations_5_speed_unit_id', u'incubations_5_duration_unit_id', 
     u'incubations_5_temperature_unit_id', u'measurement_units_2_id', 
     u'measurement_units_2_code', u'measurement_units_2_long_name', 
     u'measurement_units_2_siunitx', u'dna_extractions_1_id', 
     u'dna_extractions_1_code', u'dna_extractions_1_protocol_id', 
     u'dna_extractions_1_source_id'], 
     dtype='object') 

- ama adlandırma istediğimi seçmeme yardımcı olmaz.

Anahtar, bu veri tabanındaki orijinal tablodan anahtar isimlerini korumak için kullanılabilir mi? Örneğin. measurement_units_1_code yerine mass_unit_code olmasını isterim.

+0

Sütunları pandalara yüklendikten sonra ihtiyacınıza göre yeniden adlandıramadınız mı? –

+0

Bu sorunu gidermek için, açık bir haritalama (yalnızca bir tablo için bunu yapmadığımı söylemeye gerek yok) yazmam gerekecek ve "measurement_units_1_code" ** "**" nin "mass_unit_code" değerine karşılık geldiğinden emin olmalısınız. volume_unit_code' için. Ben ölçüm_units_1_kodundaki sayıların nasıl atandığından emin değilim, ancak gerçek anahtar ismin yerine bir sayı elde edersem çok daha iyi olurdu ... – TheChymera

cevap

1

Bu, joinedload'un ne için kullanılması gerektiği değil. Bu durumda açık bir join yapmak istiyorum: Tüm bu isimleri tip dışarı istemiyorsanız, tüm ilişkileri bulmak için DNAExtractionProtocol sınıfı incelemek ve dinamik sorgu ve etiketleri oluşturabilirsiniz

session.query(DNAExtractionProtocol.id.label("id"), 
       ..., 
       MeasurementUnit.id.label("mass_unit_id"), 
       ...) \ 
     .join(DNAExtractionProtocol.mass_unit) \ 
     .join(DNAExtractionProtocol.digestion_buffer) \ 
     ... \ 
     .filter(...) 

. Bir örnek:

cols = [] 
joins = [] 
insp = inspect(DNAExtractionProtocol) 
for name, col in insp.columns.items(): 
    cols.append(col.label(name)) 
for name, rel in insp.relationships.items(): 
    alias = aliased(rel.mapper.class_, name=name) 
    for col_name, col in inspect(rel.mapper).columns.items(): 
     aliased_col = getattr(alias, col.key) 
     cols.append(aliased_col.label("{}_{}".format(name, col_name))) 
    joins.append((alias, rel.class_attribute)) 

query = session.query(*cols).select_from(DNAExtractionProtocol) 
for join in joins: 
    query = query.join(*join) 

DÜZENLEME: Veri yapısına bağlı olarak son satırında outerjoin yerine join kullanmak gerekebilir.

Bunu beğeninize göre değiştirmeniz gerekecektir. Örneğin, bu potansiyel adlandırma çakışmalarını dikkate almaz, ör. mass_unit_id için DNAExtractionProtocol.mass_unit_id mı, yoksa MeasurementUnit.id mu? Ayrıca, str(sql_query) yerine sql_query.statement yürütmek isteyebilirsiniz. str(sql_query) yazdırma amaçlıdır, yürütme için değil. sql_query.statement kullanırsanız params=[code] geçirmeniz gerekmediğine inanıyorum çünkü code zaten sorgudaki uygun parametreye bağlanmış olacaktır.

+0

Teşekkür ederim! Sınıfımın tüm '' '' '' '' '' '' '' '' '' '' '' '' '' '' • '' '•' '' '' • '' '' '' '' • '' '' '' '' '' '' • '' '•' '' – TheChymera

+0

@TheChymera Bunun için bir örnek ekledim. – univerio

+0

Ayrıca, tablonun birleşik tablo devralması kullanması durumunda yukarıdaki kod bozuluyor (burada görüldüğü gibi (http://stackoverflow.com/questions/33869328/multiple-split-class-associations-in-sqlalchemy)). Söz konusu sınıf tarafından sağlanan anahtarlar için üst sınıfta görünüyor gibi görünüyor ve ' öğesine katılmayı denedi, ancak şu gibi hatalarla çöküyor gibi görünüyor: Herhangi bir yabancı anahtar ilişkisi bulamıyor 'protokoller' ve 'ölçüm_birimleri' arasında. – TheChymera