Я новичок в SQLAlchemy ORM, и я изо всех сил пытаюсь выполнить сложные запросы по нескольким таблицам - запросы, которые я считаю относительно простыми в Doctrine DQL.
У меня есть объекты данных городов, которые принадлежат странам.В некоторых городах также есть идентификационный номер округа, но не все.Помимо необходимых первичных и внешних ключей, каждая запись также имеет text_string_id, который ссылается на таблицу TextStrings, в которой хранится название города / округа / страны на разных языках.Таблица MySQL TextStrings выглядит следующим образом:
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`)
)
Я хочу создать хлебную крошку для каждого города в форме:
имя_ страны_имя_город_ИЛИ ИЛИ
имя_области_имя> county_en_name> city_en_name,
в зависимости от того, установлен или нет атрибут County для этого города.В Doctrine это было бы относительно просто:
$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');
С SQLAlchemy ORM я изо всех сил пытаюсь достичь того же.Я полагаю, что правильно настроил объекты - в форме, например:
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))
Моя проблема заключается в запросах - я пробовал различные подходы к созданию хлебных крошек, но, похоже, ничего не работает.Некоторые наблюдения:
Возможно, использование в запросе таких вещей, как CONCAT и IF inline, не очень питонично (возможно ли даже с ORM?) - поэтому я попытался выполнить эти операции вне SQLAlchemy, в цикле Pythonиз записей.Однако здесь я изо всех сил пытался получить доступ к отдельным полям - например, средства доступа к модели, кажется, не углубляются на n уровней, например, City.counties.text_strings.language не существует.
У меня естьтакже экспериментировал с использованием кортежей - ближе всего я работал с ним, разделив его на два запроса:
# 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
Я разделил его на два запроса, потому что не мог понять, как сделатьКостюм соединения необязательный всего в одном запросе.Но этот подход, конечно, ужасен и хуже, когда второй запрос не сработал на 100% - он не объединял все разные city.text_strings для последующей фильтрации.
Так что я в тупике!Любая помощь, которую вы можете дать мне, указав правильный путь для выполнения таких сложных запросов в SQLAlchemy ORM, была бы очень признательна.