Как записать данные pandas в MySQL? - PullRequest
0 голосов
/ 27 февраля 2020

Удивительно, но на этот вопрос еще нет ответа, и многие официальные учебные пособия устарели ...

У меня есть датафрейм (из файла .gml):

0     idBE67FFF5-E384-46D8-90C7-6BF6AB022437                 None  ...  OSOpenRoads_NU  LINESTRING (400009.35 653857.76, 399976.31 653...
1     id24E541C9-92FE-461F-9E7D-D0E1D020490F                 None  ...  OSOpenRoads_NU  LINESTRING (399946.46 653943.01, 399949.14 653...
2     id27CF83B1-CCBF-460D-A5FD-BF3C084BC2AF                 None  ...  OSOpenRoads_NU  LINESTRING (399973.3 654148.9, 399953.7 654166...
3     idE7BD08F3-16F4-447A-AB39-ABFE136770E3                 None  ...  OSOpenRoads_NU  LINESTRING (399973.3 654148.9, 399985.42 65416...
4     idF8EA8A7D-2BEE-44FE-AD50-81D11BC37951                 None  ...  OSOpenRoads_NU  LINESTRING (400046.74 653898.38, 400026.94 653...
...                                      ...                  ...  ...             ...                                                ...
6799  id9A9EBB1A-80A5-4BF3-9678-243E7FF9D244                 None  ...  OSOpenRoads_NU  LINESTRING (416894.71 601254.14, 417106.53 601...
6800  id01937359-E96B-4D9A-87AE-AF7AC1573C96                 None  ...  OSOpenRoads_NU  LINESTRING (417315.89 600917.08, 417396.94 600...
6801  id8488F0BF-6B33-401E-9F91-533E2464FA20                 None  ...  OSOpenRoads_NU  LINESTRING (417668.09 600692.51, 417621.26 600...
6802  id8E31C24A-B173-4B91-9D81-A5CD9860409F                 None  ...  OSOpenRoads_NU  LINESTRING (417646 600257, 417641.4 600260.180...
6803  id27047C68-5804-4526-833D-B405C58B33E9                 None  ...  OSOpenRoads_NU  LINESTRING (417481.82 600760.71, 417470.46 600...

Каждый одна строка выглядит так:

gml_id                                                            id50670722-1C3A-41C6-920F-B707D7295D77
beginLifespanVersion                                                                                None
inNetwork                                                                                           None
fictitious                                                                                         False
validFrom                                                                                           None
roadClassification                                                                 Classified Unnumbered
roadFunction                                                                                  Minor Road
formOfWay                                                                             Single Carriageway
length                                                                                                11
length_uom                                                                                             m
loop                                                                                               False
primaryRoute                                                                                       False
trunkRoad                                                                                          False
roadClassificationNumber                                                                            None
name1                                                                                         Green Batt
geometry                    LINESTRING (418621 613116, 418615.73 613115.59, 418610.46 613115.1899999999)

У меня уже есть таблица в базе данных MySQL со всеми необходимыми полями и индексами:

CREATE TABLE `test` (
    `gml_id` VARCHAR(50) NULL DEFAULT NULL,
    `beginLifespanVersion` VARCHAR(50) NULL DEFAULT NULL,
    `inNetwork` VARCHAR(50) NULL DEFAULT NULL,
    `fictitious` VARCHAR(50) NULL DEFAULT NULL,
    `validFrom` VARCHAR(50) NULL DEFAULT NULL,
    `roadClassification` VARCHAR(50) NULL DEFAULT NULL,
    `roadFunction` VARCHAR(50) NULL DEFAULT NULL,
    `formOfWay` VARCHAR(50) NULL DEFAULT NULL,
    `length` INT NULL DEFAULT NULL,
    `length_uom` VARCHAR(3) NULL DEFAULT NULL,
    `loop` VARCHAR(50) NULL DEFAULT NULL,
    `primaryRoute` VARCHAR(50) NULL DEFAULT NULL,
    `trunkRoad` VARCHAR(50) NULL DEFAULT NULL,
    `roadClassificationNumber` VARCHAR(50) NULL DEFAULT NULL,
    `name1` VARCHAR(100) NULL DEFAULT NULL,
    `geometry` LINESTRING NULL DEFAULT NULL
    INDEX `gml_id` (`gml_id`),
    INDEX `roadClassification` (`roadClassification`),
    INDEX `roadFunction` (`roadFunction`),
    INDEX `formOfWay` (`formOfWay`),
    INDEX `primaryRoute` (`primaryRoute`),
    INDEX `roadClassificationNumber` (`roadClassificationNumber`),
    INDEX `name1` (`name1`)
)
COLLATE='utf8mb4_0900_ai_ci'
ENGINE=InnoDB
;

Мой текущий код python :

            roads   = geopandas.read_file(path)
        ## here I have proper output as upper

            import config_db as cfgdb
            from sqlalchemy import create_engine, MetaData, Table
            # from shapely.geometry import Linestring
            engine = create_engine('mysql+mysqlconnector://'+cfgdb.user+':'+cfgdb.password+'@'+cfgdb.host+':'+cfgdb.port+'/'+cfgdb.database, echo=cfgdb.echo)
       ## it seems to be connected to database w/o any problems

            roads.to_sql(table, engine, if_exists='replace', index=False,dtype={'geometry': Geometry('LINESTRING', srid=27700)})
       ## this fails

Вопрос : как загрузить все данные из геоданных в эту таблицу - сохранить пространственный тип столбца геометрии в GDF в таблице?

Теоретически это должно быть очень простым, но я борюсь с ошибками типа:

mysql .connector.errors.ProgrammingError: 1305 (42000): FUNCTION md.ST_GeomFromEWKT не существует

sqlalchemy.ex c .InvalidRequestError: Не удалось отразить: запрошенные таблицы недоступны в Engine

и т. Д. *

Версии, которые я использую: MySQL 8.0.19, новейшие гео Pandas, геоалхимия, sqlalchemy, Python 3.8

...