Я надеюсь, у вас работают пилоны; для всех, кто может позже прочитать вопрос, я приведу несколько указателей в правильном направлении.
Прежде всего, вы только создаете движок и объект метаданных. Хотя вы можете использовать движок для непосредственного создания соединений, вы почти всегда используете сеанс для управления запросами и обновлением базы данных.
Pylons автоматически настраивает это для вас, создавая движок из вашего файла конфигурации, затем передавая его в yourproject.model.__init__.py:init_model()
, который связывает его с scoped_session
объектом.
Этот объект scoped_session доступен с yourproject.model.meta
и является объектом, который вы бы использовали для запроса вашей базы данных. Например:
record = meta.Session.query(model.MyTable).filter(id=42)
Поскольку это scoped_session, он автоматически создает объект Session и связывает его с текущим потоком, если он еще не существует. Scoped_session передает все действия (.query (), .add (), .delete ()) в реальный объект Session и, таким образом, позволяет вам простым способом взаимодействовать с базой данных с необходимостью явно управлять не-поточно-безопасным объектом Session .
Объект scoped_session
, Session
из yourproject.model.meta
автоматически связывается с объектом метаданных, созданным как yourproject.model.meta:metadata
(в пилонах 0.9.7 и ниже) или yourproject.model.meta:Base.metadata
(в пилонах 1.0). Используйте этот объект метаданных для определения ваших таблиц. Как вы можете видеть в более новых версиях пилонов, метаданные связаны с declarative_base()
объектом с именем Base
, что позволяет вам использовать декларативный стиль SqlAlchemy.
Использование этого с контроллера
from yourproject import model
from yourproject.model import Session
class MyController(..):
def resource(self):
result = Session.query(model.email_list).\
filter(model.email_list.c.id=42).one()
return str(result)
Использовать реальные соединения
Если вы действительно хотите получить объект подключения, просто используйте
from yourproject.model import Session
connection = Session.connection()
result = connection.execute("select 3+4;")
// more connection executions
Session.commit()
Однако это все хорошо, но то, что вы должны делать, это ...
Это исключает, что вы на самом деле не очень много используете SqlAlchemy. Сила SqlAlchemy действительно сияет, когда вы начинаете отображать таблицы базы данных в классы Python. Поэтому любой, кто хочет использовать пилоны с базой данных, должен серьезно взглянуть на то, что вы можете сделать с помощью SqlAlchemy. Если SqlAlchemy начинает пугать, просто начните с его декларативного подхода, которого должно быть достаточно почти для всех приложений пилонов.
В вашей модели вместо определения табличных конструкций сделайте следующее:
from sqlalchemy import Column, Integer, Unicode, ForeignKey
from sqlalchemy.orm import relation
from yourproject.model.meta import Base
class User(Base):
__tablename__ = 'users'
# primary_key implies nullable=False
id = Column(Integer, primary_key=True, index=True)
# nullable defaults to True
name = Column(Unicode, nullable=False)
notes = relation("UserNote", backref="user")
query = Session.query_property()
class UserNote(Base):
__tablename__ = 'usernotess'
# primary_key implies nullable=False
id = Column(Integer, primary_key=True, index=True)
userid = Column(Integer, index=True, ForeignKey("User.id"))
# nullable defaults to True
text = Column(Unicode, nullable=False)
query = Session.query_property()
Обратите внимание на объекты запроса. Это смарт-объекты, которые живут в классе и связывают ваши классы с scoped_session()
, Session. Это позволяет вам легче извлекать данные из вашей базы данных.
from sqlalchemy.orm import eagerload
def resource(self):
user = User.query.filter(User.id==42).options(eagerload("notes")).one()
return "\n".join([ x.text for x in user.notes ])