我正在使用MySQLdb包与MySQL进行交互。我无法获得正确的类型转换。
我使用一个16字节的二进制uuid作为表的主键,并且有一个midblob保存zlib压缩的json信息。
我正在使用以下架构:
CREATE TABLE repositories (
added_id int auto_increment not null,
id binary(16) not null,
data mediumblob not null,
create_date int not null,
update_date int not null,
PRIMARY KEY (added_id),
UNIQUE(id)
) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ENGINE=InnoDB;
然后我使用以下代码在表中创建一个新行:
data = zlib.compress(json.dumps({'hello':'how are you :D'})
row_id = uuid.uuid(4).hex
added_id = cursor.execute('
INSERT INTO repositories (id, data, create_date, update_date)
VALUES (%s, %s, %s, %s)',
binascii.a2b_hex(row_id),
data,
time.time(),
time.time()
)
然后检索数据我使用类似的查询:
query = cursor.execute('SELECT added_id, id, data, create_date, update_date ' \
'FROM repositories WHERE id = %s',
binascii.a2b_hex(row_id)
)
然后查询返回一个空结果。
任何帮助将不胜感激。另外,最好将unix纪元日期存储为整数还是TIMESTAMP?
注意:我没有插入数据的问题,只是试图从数据库中检索它。当我通过mysqlclient检查时,该行存在。
非常感谢!@
答案 0 :(得分:7)
一个提示:您应该可以致电uuid.uuid4().bytes
获取原始资料
字节。至于时间戳,如果你想执行时间/日期操作
在SQL中,处理真正的TIMESTAMP类型通常更容易。
我创建了一个测试表来尝试重现您所看到的内容:
CREATE TABLE xyz (
added_id INT AUTO_INCREMENT NOT NULL,
id BINARY(16) NOT NULL,
PRIMARY KEY (added_id),
UNIQUE (id)
) DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ENGINE=InnoDB;
我的脚本能够使用二进制字段作为插入和查询行 关键没有问题。也许你错误地获取/迭代了 光标返回的结果?
import binascii
import MySQLdb
import uuid
conn = MySQLdb.connect(host='localhost')
key = uuid.uuid4()
print 'inserting', repr(key.bytes)
r = conn.cursor()
r.execute('INSERT INTO xyz (id) VALUES (%s)', key.bytes)
conn.commit()
print 'selecting', repr(key.bytes)
r.execute('SELECT added_id, id FROM xyz WHERE id = %s', key.bytes)
for row in r.fetchall():
print row[0], binascii.b2a_hex(row[1])
输出:
% python qu.py
inserting '\x96\xc5\xa4\xc3Z+L\xf0\x86\x1e\x05\xebt\xf7\\\xd5'
selecting '\x96\xc5\xa4\xc3Z+L\xf0\x86\x1e\x05\xebt\xf7\\\xd5'
1 96c5a4c35a2b4cf0861e05eb74f75cd5
% python qu.py
inserting '\xac\xc9,jn\xb2O@\xbb\xa27h\xcd<B\xda'
selecting '\xac\xc9,jn\xb2O@\xbb\xa27h\xcd<B\xda'
2 acc92c6a6eb24f40bba23768cd3c42da
答案 1 :(得分:3)
要补充现有答案,在处理查询中的二进制字符串时,还会出现以下警告问题:
Warning: (1300, "Invalid utf8 character string: 'ABCDEF'")
由以下内容复制:
cursor.execute('''
CREATE TABLE `table`(
bin_field` BINARY(16) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
''')
bin_value = uuid.uuid4().bytes
cursor.execute('INSERT INTO `table`(bin_field) VALUES(%s)', (bin_value,))
每当MySQL发现查询中的字符串文字对当前character_set_connection
无效时,它就会发出警告。有几种解决方案:
明确设置_binary
charset literal
INSERT INTO `table`(bin_field) VALUES(_binary %s)
INSERT INTO `table`(bin_field) VALUES(x'abcdef')
如果您只使用二进制字符串
有关详细信息,请参阅MySQL Bug 79317。
正如@charlax指出的那样,有binary_prefix
标志可以传递给连接的初始化器,以便在插入argumentsmet时自动添加_binary
前缀。它的最新版本mysql-client和pymysql支持它。