Wie Sie mehrere Tabellen Abfragen in SQLAlchemy ORM

Ich bin ein Neuling in SQLAlchemy ORM und ich bin kämpfen, um Sie zu erreichen, Komplex-ish-Abfragen auf mehreren Tabellen - Abfragen, die finde ich relativ einfach zu tun, die in Lehre DQL.

Ich habe Daten von Objekten der Städte, die gehören zu den Ländern. Einige Städte haben auch eine County-ID setzen, aber nicht alle. Sowie die erforderlichen primär-und Fremdschlüssel, jeder Datensatz hat auch eine text_string_id, die links zu einer TextStrings Tabelle speichert den Namen der Stadt/Landkreis/Land in verschiedenen Sprachen. Die TextStrings MySQL-Tabelle sieht wie folgt aus:

CREATE TABLE IF NOT EXISTS `text_strings` (
    `id` INT UNSIGNED NOT NULL,
    `language` VARCHAR(2) NOT NULL,
    `text_string` varchar(255) NOT NULL,
    PRIMARY KEY (`id`, `language`)
)

Will ich bauen einen breadcrumb für jede Stadt, von der form:

country_en_name > city_en_name ODER

country_en_name > county_en_name > city_en_name,

je nachdem, ob oder nicht eine County-Attribut festgelegt ist, werden für diese Stadt. In der Lehre wäre dies relativ einfach:

    $query = Doctrine_Query::create()
                ->select('ci.id, CONCAT(cyts.text_string, \'> \', IF(cots.text_string is not null, CONCAT(cots.text_string, \'> \', \'\'), cits.text_string) as city_breadcrumb')
                ->from('City ci')
                ->leftJoin('ci.TextString cits')
                ->leftJoin('ci.Country cy')
                ->leftJoin('cy.TextString cyts')
                ->leftJoin('ci.County co')
                ->leftJoin('co.TextString cots')
                ->where('cits.language = ?', 'en')
                ->andWhere('cyts.language = ?', 'en')
                ->andWhere('(cots.language = ? OR cots.language is null)', 'en');

Mit SQLAlchemy ORM, ich habe Mühe, das gleiche zu erreichen. Ich glaube, ich habe setup die Objekte korrekt in der form zB:

class City(Base):
    __tablename__ = "cities"

    id = Column(Integer, primary_key=True)
    country_id = Column(Integer, ForeignKey('countries.id'))
    text_string_id = Column(Integer, ForeignKey('text_strings.id'))
    county_id = Column(Integer, ForeignKey('counties.id'))

    text_strings = relation(TextString, backref=backref('cards', order_by=id))
    country = relation(Country, backref=backref('countries', order_by=id))
    county = relation(County, backref=backref('counties', order_by=id))

Mein problem ist in der Abfrage - ich hab versucht verschiedene Ansätze zur Generierung der breadcrumb-aber nichts scheint zu funktionieren. Einige Beobachtungen:

Vielleicht mit Dingen wie CONCAT, und WENN Sie inline in die Abfrage ist nicht sehr pythonic (ist es sogar möglich, mit dem ORM -?) - also habe ich versucht, die Ausführung dieser Operationen außerhalb SQLAlchemy, Python-Schleife die Datensätze. Allerdings habe ich hier gekämpft, um den Zugriff auf die einzelnen Felder - beispielsweise das Modell Accessoren scheinen nicht zu gehen n-Ebenen, z.B. die Stadt.Grafschaften.text_strings.Sprache existiert nicht.

Habe ich experimentierte auch mit Tupel - der nächste, den ich habe, um es tätig war, durch Aufteilung in zwei Abfragen:

# For cities without a county
for city, country in session.query(City, Country).\
    filter(Country.id == City.country_id).\
    filter(City.county_id == None).all():

    if city.text_strings.language == 'en':
    # etc

# For cities with a county
for city, county, country in session.query(City, County, Country).\
    filter(and_(City.county_id == County.id, City.country_id == Country.id)).all():

    if city.text_strings.language == 'en':
    # etc

Ich spaltete es sich in zwei Abfragen, da ich nicht herausfinden konnte, wie man den Anzug join optional in nur einer Abfrage. Aber dieser Ansatz ist natürlich schrecklich und noch schlimmer die zweite Abfrage hat nicht funktioniert 100%, es war nicht beitreten alle anderen Stadt.text_strings für eine anschließende Filterung.

So, ich bin ratlos! Jede Hilfe, die Sie mir geben können, ich wäre auf dem richtigen Weg für die Durchführung dieser Art von komplexen-ish-Abfragen in SQLAlchemy ORM wäre sehr geschätzt werden.

InformationsquelleAutor Alex Dean | 2011-01-06
Schreibe einen Kommentar