SQLAlchemy 1.1.1忽略了lazy ='加入'

时间:2017-03-03 04:06:54

标签: python sqlalchemy mariadb

您是否曾经发现如果在 session.query()之后放置 commit(),则会对查询中的每一行单独执行SQL,SQLAlchemy 忽略模型定义中的lazy ='joined'

 ENGINE = create_engine("mysql+pymysql://........")
 SESS = sessionmaker(bind=ENGINE)     
 session = SESS()
 try:
    session.query(Document).order_by(desc('number'))[0:5]
    session.commit()
 except:
    session.rollback()
    raise

模型与往常一样:

class Document(BASE):
   """ Document mapping """
   __tablename__ = "document"

   id = Column(Integer, primary_key=True)
   number = Column(String)
   currency_id = Column(Integer, ForeignKey('currency.id'))
   currency = relationship("Currency", lazy='joined')

class Currency(BASE):
   """ Currency mapping """
   __tablename__ = "currency"
   label = Column(String)
   id = Column(Integer, primary_key=True)

没有 session.commit() SQL是:

    70306 10:32:52    149 Connect   venice@localhost as anonymous on venice
          149 Query SET AUTOCOMMIT = 0
          149 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id, currency_1.label AS currency_1_label, currency_1.created_at AS currency_1_created_at, currency_1.updated_at AS currency_1_updated_at, currency_1.id AS currency_1_id
FROM document LEFT OUTER JOIN currency AS currency_1 ON currency_1.id = document.currency_id ORDER BY document.number ASC
 LIMIT 5

但是 session.commit() SQL是:

170306 10:31:58   147 Connect   venice@localhost as anonymous on venice
          147 Query SET AUTOCOMMIT = 0
          147 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id, currency_1.label AS currency_1_label, currency_1.created_at AS currency_1_created_at, currency_1.updated_at AS currency_1_updated_at, currency_1.id AS currency_1_id
FROM document LEFT OUTER JOIN currency AS currency_1 ON currency_1.id = document.currency_id ORDER BY document.number ASC
 LIMIT 5
          147 Query COMMIT
          147 Query ROLLBACK
          147 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id
FROM document
WHERE document.id = 4357
          147 Query SELECT currency.label AS currency_label, currency.created_at AS currency_created_at, currency.updated_at AS currency_updated_at, currency.id AS currency_id
FROM currency
WHERE currency.id = 1
          147 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id
FROM document
WHERE document.id = 293
          147 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id
FROM document
WHERE document.id = 569
          147 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id
FROM document
WHERE document.id = 6521
          147 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id
FROM document
WHERE document.id = 7614

当生成异常时,例如欺骗场造成的:

documents = session \
                .query(Document) \
                .order_by(asc("bad_field"))[0:20]

然后python输出:

InternalError: (pymysql.err.InternalError) (1054, u"Unknown column 'bad_field' in 'order clause'") [SQL: u'SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id, currency_1.label AS currency_1_label, currency_1.created_at AS currency_1_created_at, currency_1.updated_at AS currency_1_updated_at, currency_1.id AS currency_1_id \nFROM document LEFT OUTER JOIN currency AS currency_1 ON currency_1.id = document.currency_id ORDER BY bad_field ASC \n LIMIT %(param_1)s'] [parameters: {u'param_1': 20}]

和MariaDB日志:

170306 23:29:09   195 Connect   venice@localhost as anonymous on venice
      195 Query SET AUTOCOMMIT = 0
      195 Query SHOW VARIABLES LIKE 'sql_mode'
      195 Query SELECT DATABASE()
      195 Query SELECT @@tx_isolation
      195 Query show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin'
      195 Query SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
      195 Query SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
      195 Query SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin AS anon_1
      195 Query ROLLBACK
      195 Query SELECT document.id AS document_id, document.number AS document_number, document.currency_id AS document_currency_id, currency_1.label AS currency_1_label, currency_1.created_at AS currency_1_created_at, currency_1.updated_at AS currency_1_updated_at, currency_1.id AS currency_1_id FROM document LEFT OUTER JOIN currency AS currency_1 ON currency_1.id = document.currency_id ORDER BY bad_field ASC LIMIT 20
      195 Query ROLLBACK
      195 Query ROLLBACK

0 个答案:

没有答案