使用 SQLAlchemy
的混合属性进行查询时报错: TypeError: Python 'method' cannot be converted to a MySQL type
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `user` VALUES ('1', 'a');
INSERT INTO `user` VALUES ('2', 'b');
INSERT INTO `user` VALUES ('3', 'c');
SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
DROP TABLE IF EXISTS `password`;
CREATE TABLE `password` (
`id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
INSERT INTO `password` VALUES ('84a516841ba77a5b4648de2cd0dfcb30ea46dbb4', 'abc123');
INSERT INTO `password` VALUES ('86f7e437faa5a7fce15d1ddcb9eaeaea377667b8', '123456');
INSERT INTO `password` VALUES ('e9d71f5ee7c92d6dc9e92ffdad17b8bd49418f98', 'abcdef');
SET FOREIGN_KEY_CHECKS = 1;
password.id
是 user.name
hash后的结果
test.py
import hashlib
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(String(20), primary_key=True)
name = Column(String(20))
@hybrid_property
def hash(self):
# return '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8'
return hashlib.sha1(bytes(self.name, encoding='utf-8')).hexdigest()
@hybrid_method
def hash(self):
return hashlib.sha1(bytes(self.name, encoding='utf-8')).hexdigest() # 该方法一定得可转为SQL的方法
class Password(Base):
__tablename__ = 'password' # 表名
id = Column(String(20), primary_key=True)
password = Column(String(20))
def __repr__(self):
return '{} {}'.format(self.id, self.password)
engine = create_engine('mysql+mysqlconnector://root:123456@localhost:3306/test') # 用户名root,口令123456
DBSession = sessionmaker(bind=engine)
session = DBSession()
# 这样不行
print(session.query(Password).join(User, Password.id == User.hash).filter(User.id == '1').one())
# 这样也不行
# stmt = session.query(User).filter(User.id == '1').subquery()
# print(session.query(Password).filter(Password.id == stmt.hash).one())
session.close()
SQLAlchemy对混合属性进行Python操作,其Python操作必须在SQL中,否则会报该错误
因此本人觉得只能分开查询,因为hash操作是Python层面的东西,很难转换到SQL
import hashlib
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, String, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column(String(20), primary_key=True)
name = Column(String(20))
@hybrid_property
def hash(self):
# return '86f7e437faa5a7fce15d1ddcb9eaeaea377667b8'
return hashlib.sha1(bytes(self.name, encoding='utf-8')).hexdigest()
class Password(Base):
__tablename__ = 'password' # 表名
id = Column(String(20), primary_key=True)
password = Column(String(20))
def __repr__(self):
return '{} {}'.format(self.id, self.password)
engine = create_engine('mysql+mysqlconnector://root:123456@localhost:3306/test') # 用户名root,口令123456
DBSession = sessionmaker(bind=engine)
session = DBSession()
# 这样不行
# print(session.query(Password).join(User, Password.id == User.hash).filter(User.id == '1').one())
# 这样也不行
# stmt = session.query(User).filter(User.id == '1').subquery()
# print(session.query(Password).filter(Password.id == stmt.hash).one())
# 分开查询
user = session.query(User).filter(User.id == '1').one()
hash = user.hash
password = session.query(Password).filter(Password.id == hash).one()
print(password)
session.close()