Моят личен и професионален живот

2018-05-15

MySQL Shell и автоматичното създаване на идентификтори за документи

Защо получавам грешка ERROR: 5115: Document is missing a required field в MySQL Shell 8.0.11 свързан към MySQL 5.7.22 сървър? Разгледайте следната сесия в която първо се свързвам към сървъра, създавам нова схема, след това колекция вътре в схемата и накрая се опитвам да създам документ без явно да предоставям идентификатор:

MySQL Shell 8.0.11

Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type '\help' or '\?' for help; '\quit' to exit.


MySQL JS> \connect root@server
Creating a session to 'root@
server'
Enter password: ************
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 1027578 (X protocol)
Server version: 5.7.22-log Source distribution
No default schema selected; type \use schema to set one.

MySQL [server+ ssl] JS> session.createSchema('test')
<schema:test>

MySQL [
server+ ssl] JS> \use test
Default schema `test` accessible through db.

MySQL [
server+ ssl/test] JS> per_coll = db.createCollection('persons')
<collection:persons>

MySQL [
server+ ssl/test] JS> per_coll.add({name:'Georgi'})
ERROR: 5115: Document is missing a required field

MySQL [
server+ ssl/test] JS> \py
Switching to Python mode...

MySQL [server+ ssl/test] Py> pcol = db.get_collection('persons')

MySQL [server+ ssl/test] Py> pcol.add({'name':'Georgi'})
ERROR: 5115: Document is missing a required field


В този случай MySQL Shell трябва да създаде идентификатор както е указано в наръчника (виж Наръчника за MySQL 5.7, глава 19.4.4.2 Add Documents), където е написано:
Each document requires an identifier field called _id. The value of the _id field must be unique among all documents in the same collection. If the document passed to the add() method does not contain the _id field, MySQL Shell automatically inserts a field into the document and sets the value to a generated universal unique identifier (UUID).
При свързване към MySQL 8.0 сървър няма такъв проблем:

MySQL Shell 8.0.11

Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type '\help' or '\?' for help; '\quit' to exit.


MySQL JS> \connect root@mysql8
Creating a session to 'root@mysql8'
Enter password: ************
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 6646 (X protocol)
Server version: 8.0.11 Source distribution
No default schema selected; type \use <schema> to set one.

MySQL [mysql8+ ssl] JS> session.createSchema('test')
<schema:test>

MySQL [mysql8+ ssl] JS> \use test
Default schema `test` accessible through db.

MySQL [mysql8+ ssl/test] JS> per_coll = db.createCollection('persons')
<collection:persons>

MySQL [mysql8+ ssl/test] JS> per_coll.add({name:'Georgi'})
Query OK, 1 item affected (0.2450 sec)


MySQL [192.168.79.46+ ssl/test2] JS> per_coll.find()
[
    {
        "_id": "00005adc69630000000000000002",
        "name": "Georgi"
    }
]
1 document in set (0.2035 sec)


Опитах също и с MySQL Shell 1.0 и отново няма проблем:

$ mysqlsh
MySQL Shell 1.0.11

Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type '\help' or '\?' for help; '\quit' to exit.

Currently in Python mode. Use \sql to switch to SQL mode and execute queries.
mysql-py> \connect root@localhost
Creating a Session to 'root@localhost'
Enter password:
Your MySQL connection id is 1028442 (X protocol)
Server version: 5.7.22-log Source distribution
No default schema selected; type \use <schema> to set one.
mysql-py> session.create_schema('test')
<schema:test>
mysql-py> \use test
Schema `test` accessible through db.
mysql-py> pcol = db.create_collection('persons')
mysql-py> pcol.add({'name':'Georgi'})
Query OK, 1 item affected (0.16 sec)
mysql-py> pcol.find()
[
    {
        "_id": "aa0960462c58e811b27610feed07afc3",
        "name": "Georgi"
    }
]
1 document in set (0.00 sec)


Публикацията MySQL Document Store Document IDs. на Dave Stokes е първия (и всъщност единствен) резултат в Google за грешката (при търсене за точно съвпадение с двойни кавички). Публикацията насочва към глава 5.1.1 Understanding Document IDs от X DevAPI User Guide, където четем:
X DevAPI relies on server based document ID generation, added in MySQL version 8.0.11, which results in sequentially increasing document IDs across all clients.
...
Whenever an _id field value is not present in an inserted document, the server generates an _id value.
Която изяснява проблема. Явно, MySQL Shell 8.0.11 очаква сървъра да създаде идентификатор (за колоната _id) без да взима в предвид дали той е версия 5.7 или 8.0, което за мен е бъг, който трябва да докладвам по-късно.

Обновяване 2018-05-16: Oracle провериха бъг доклада ми (виж bug 90876). Надявам се, че ще бъде оправен.

Няма коментари: