python - SQLalchemy Primaryjoin 属性在 Python 3.4 中不起作用(使用 Python 2.7 起作用)

标签 python mysql python-2.7 sqlalchemy python-3.4

我最近尝试将代码从 Python 2.7 升级到 Python 3.4。

在 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(以及根据 Python 3.4 从源代码编译的 mod_wsgi 4.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)并填写参数(一个)进行 SQL 查询,它理解该查询并得出有效的结果。

我尝试过以其他形式编写 primaryjoin,例如不带字符串、使用 or_ 和使用“|”作为或运算符。还尝试了 in_ - 运算符。

我使用 Ubuntu 14.04 和 mod_wsgi 4.4、SQLalchemy 1.0.12 和 Flask-SQLalchemy 2.1。

我正在使用python3-mysql.connector(MySQL Connector/Python 的 Ubuntu 软件包)。

如果我删除其中一个相等比较(无论是哪一个)并且不使用 or_ 运算符,那么它不会引发错误。但我需要同时使用 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:password@127.0.0.1/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 AS coupleproposal_participantID, coupleproposal.volunteerID AS coupleproposal_volunteerID \nFROM coupleproposal \nWHERE %(param_1)s = coupleproposal.participantID OR %(param_1)s = coupleproposal.volunteerID'] [parameters: {'param_1': 1}]

最佳答案

如果我使用不同的连接器(例如 pymysql),它就可以工作。在这里回答(不是我,而是 SQLalchemy 的仓库所有者):https://bitbucket.org/zzzeek/sqlalchemy/issues/3669/primaryjoin-attribute-with-or_-operator

关于python - SQLalchemy Primaryjoin 属性在 Python 3.4 中不起作用(使用 Python 2.7 起作用),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35814911/

相关文章:

python - 在类方法内部定义时,信息级别日志记录消息不会在 Debug模式下打印

python - scikit-learn 中 train_test_split() 的不稳定行为

php - Codeigniter 2.1,MySQL - 两个左连接

php - 无法获得使用 ajax 和 php 的点击功能

python-2.7 - 如果用户关键字在 Robot Framework 2.8.5 中包含持续失败,则不会返回任何值

python - 在 python 中使用 lambda 函数创建差异数组

python - 为什么 Python 的 namedtuple 实例是从字符串模板创建的?

python - 特定 bin 内 numpy 数组的元素数量

MYSQL - 在选择和分组依据中将多列显示为不同的值

python - Python:两个大型numpy数组之间的余弦相似度