2016-01-26 2 views
1

Я всего лишь два дня изучая SQLAlchemy и задаю вопрос о сопоставлении имен столбцов. Во-первых, следующее заявление в официальных документы бросил меня баланс:Сопоставление столбцов в SQLAlchemy

Matching колонны по имени работает для простых случаев, но может стать громоздким при работе со сложными заявлениями, которые содержат повторяющиеся имена столбцов или при использовании анонимизированных ОРМ конструкций, которые нелегко соответствуют конкретным именам. Кроме того, в наших сопоставленных столбцах присутствует типизированное поведение , которое может понадобиться, когда обрабатывает строки результатов.

Ух, что ?! Пример или два из того, что этот параграф пытается сказать, было бы здорово, но неважно; это задача на другой день.

Я понял, что иногда список полей, сгенерированный нашим запросом, не идеально согласуется с моделью, поэтому мы можем определять ожидаемые столбцы позиционно. Это заставило меня попытаться придумать пример, где это сопоставление может быть полезно. Поэтому я подумал, как насчет выбора столбца из таблицы, который вычисляется на лету? Я моделируется это в базе данных sqlite с помощью функции random() так:

from sqlalchemy import create_engine 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import Column, Integer, String 
from sqlalchemy.orm import sessionmaker 

engine = create_engine('sqlite:///:memory:', echo=True) 
Base = declarative_base() 

Session = sessionmaker(bind=engine) 
session = Session() 

class User(Base): 
    __tablename__ = 'users' 
    id  = Column(Integer, primary_key=True) 
    name  = Column(String) 
    fullname = Column(String) 
    password = Column(String) 

    def __repr__(self): 
     return "User<name={}, fullname={}, password={}>".format(self.name, self.fullname, self.password) 

# Create all tables 
Base.metadata.create_all(engine) 

ed_user = User(name='ed', fullname='Ed Jones', password='edspassword') 
session.add(ed_user) 
session.add_all([ 
    User(name='wendy', fullname='Wendy Williams', password='foobar'), 
    User(name='mary', fullname='Mary Contrary', password='xxg527'), 
    User(name='fred', fullname='Fred Flinstone', password='blah') 
]) 
session.commit() 

stmt = text("SELECT name, id, fullname, random() FROM users WHERE name=:name") 
stmt = stmt.columns(User.name, User.id, User.fullname ... 

что теперь? Я не могу написать имя столбца, потому что ничего не существует, и я не могу добавить его в определение модели, потому что этот столбец будет создан без необходимости. Все, что я хотел получить дополнительную информацию из базы данных (например, NOW()), которую я могу использовать в коде.

Как это можно сделать?

ответ

1

Вы можете использовать column labels

from sqlalchemy import func 

users = session.query(User.id, User.name, User.fullname, func.random().label('random_value')) 
for user in users: 
    print(user.id, user.name, user.fullname, user.random_value) 
+0

Спасибо! Я начинал думать, что никто не придет мне на помощь (и сам нашел ограниченное решение), но это то, что я искал. – dotslash

0

Все правильно, так что я, кажется, понял это сам (блин, что в два раза в день! SQLAlchemy сообщества здесь, кажется мертвым, что заставляет меня искать отвечает на меня ... не очень плохо, хотя!). Вот как я это сделал:

from sqlalchemy import func 
session.query(User.name, User.id, User.fullname, func.current_timestamp()).filter(User.name=='ed').all() 
0

Попробуйте указать листинг column объектов. Таким образом, «random()» может быть любым произвольным SQL-вычислением столбца ...

# You may have already imported column, but for completeness: 
from sqlalchemy import column 

# As an example: 
find_name = 'wendy' 

stmt = text("SELECT name, id, fullname, (random()) as random_value FROM users WHERE name=:name") 
stmt = stmt.columns(column('name'), column('id'), column('fullname'), column('random_value')) 

users = session.query(column('name'), column('id'), column('fullname'), column('random_value')).from_statement(stmt).params(name = find_name) 
for user in users: 
    print(user.id, user.name, user.fullname, user.random_value) 
Смежные вопросы