我最近嘗試將我們的代碼從Python 2.7升級到Python 3.4。SQLalchemy primaryjoin屬性不能在Python 3.4中工作(使用Python 2.7)
在Python 2.7這只是工作:
class Maatje(CommonColumns):
koppelvoorstellen = db.relationship("Koppelvoorstel",
primaryjoin="or_(Maatje.id == Koppelvoorstel.deelnemerID," \
+ "Maatje.id == Koppelvoorstel.vrijwilligerID)",
cascade="all,delete-orphan")
但使用Python 3.4(和mod_wsgi的4.4從源代碼編譯反對的Python 3.4)我得到一個錯誤,當我嘗試查詢Maatje,在我的Apache 2.4的錯誤日誌:
[wsgi:error] [pid 6169] sqlalchemy.exc.ProgrammingError:
(mysql.connector.errors.ProgrammingError) 1064 (42000): You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near '%(param_1)s =
koppelvoorstel.`vrijwilligerID`' at line 3 [SQL: 'SELECT
koppelvoorstel.id AS koppelvoorstel_id, koppelvoorstel.aangemaakt AS
koppelvoorstel_aangemaakt, koppelvoorstel.gewijzigd AS
koppelvoorstel_gewijzigd, koppelvoorstel.etag AS koppelvoorstel_etag,
koppelvoorstel.`deelnemerID` AS `koppelvoorstel_deelnemerID`,
koppelvoorstel.`vrijwilligerID` AS `koppelvoorstel_vrijwilligerID`,
koppelvoorstel.akkoordvrijwilliger AS
koppelvoorstel_akkoordvrijwilliger, koppelvoorstel.akkoorddeelnemer AS
koppelvoorstel_akkoorddeelnemer,
koppelvoorstel.redenafwijzingvrijwilliger AS
koppelvoorstel_redenafwijzingvrijwilliger,
koppelvoorstel.redenafwijzingdeelnemer AS
koppelvoorstel_redenafwijzingdeelnemer, koppelvoorstel.stopdatum AS
koppelvoorstel_stopdatum, koppelvoorstel.redenstoppenvrijwilliger AS
koppelvoorstel_redenstoppenvrijwilliger,
koppelvoorstel.redenstoppendeelnemer AS
koppelvoorstel_redenstoppendeelnemer \\nFROM koppelvoorstel \\nWHERE %
(param_1)s = koppelvoorstel.`deelnemerID` OR %(param_1)s =
koppelvoorstel.`vrijwilligerID`'] [parameters: {'param_1': 1}]
看起來像完全有效的SQL給我(我假設\\ n將成爲一個換行符)。我嘗試了使用phpMyAdmin(不含\ n's)的SQL查詢並使用填充的參數(一個),並且它理解查詢並提出了有效的結果。
我試過用其他形式寫primaryjoin
,比如沒有字符串,用or_和「|」作爲或運營商。還嘗試了in_
- 管理員。
我使用的是Ubuntu 14.04的mod_wsgi 4.4,SQLalchemy 1.0.12和Flask-SQLalchemy 2.1。
我正在使用python3-mysql.connector
(用於MySQL連接器/ Python的Ubuntu軟件包)。
如果我刪除其中一個相等比較(無關緊要)並且不使用or_
-operator,那麼它不會引發錯誤。但我需要使用or_
-操作員。
2016年3月6日: 現在我已經將問題隔離了一下。運行與python2.7下面的代碼是沒有問題的:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_ECHO'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+mysqlconnector://username:[email protected]/primaryjoindb'
db = SQLAlchemy(app)
class Coupleproposal(db.Model):
__tablename__ = 'coupleproposal'
id = db.Column(db.Integer, primary_key=True)
participantID = db.Column(db.Integer, db.ForeignKey('buddy.id'), nullable = False)
volunteerID = db.Column(db.Integer, db.ForeignKey('buddy.id'), nullable = False)
participant = db.relationship("Buddy", foreign_keys=[participantID])
volunteer = db.relationship("Buddy", foreign_keys=[volunteerID])
__table_args__ = (db.UniqueConstraint('participantID', 'volunteerID', name='_couple_uc'),)
class Buddy(db.Model):
__tablename__ = 'buddy'
id = db.Column(db.Integer, primary_key=True)
coupleproposals = db.relationship("Coupleproposal", \
primaryjoin="(Buddy.id == Coupleproposal.participantID) | (Buddy.id == Coupleproposal.volunteerID)", \
cascade="all,delete-orphan")
db.create_all()
b1 = Buddy()
b2 = Buddy()
db.session.add(b1)
db.session.add(b2)
cp1 = Coupleproposal(participantID=1, volunteerID=1)
db.session.add(cp1)
db.session.commit()
for aBuddy in db.session.query(Buddy).all():
print(aBuddy.id)
print(aBuddy.coupleproposals)
但使用了python3.4代碼引發此錯誤:
sqlalchemy.exc.ProgrammingError: (mysql.connector.errors.ProgrammingError) 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%(param_1)s = coupleproposal.
volunteerID
' at line 3 [SQL: 'SELECT coupleproposal.id AS coupleproposal_id, coupleproposal.participantID
AScoupleproposal_participantID
, coupleproposal.volunteerID
AScoupleproposal_volunteerID
\nFROM coupleproposal \nWHERE %(param_1)s = coupleproposal.participantID
OR %(param_1)s = coupleproposal.volunteerID
'] [parameters: {'param_1': 1}]