Я создал столбец, представляющий собой Postgres массив типа Enum. Когда я пытаюсь вставить данные, я получаю длинную трассировку, сообщение об ошибке, которое кажется актуальным:
psycopg2.errors.DatatypeMismatch: column "selected_groceries" is of type groceryenum[] but expression is of type text[]
from flask_sqlalchemy import SQLAlchemy
from marshmallow import Schema, fields
from marshmallow_enum import EnumField
import enum
# ensure to connect it to a postgresdb
db = SQLAlchemy()
Column = db.Column
class CustomCreateMixin:
@classmethod
def create(cls, **kwargs):
"""Create a new record and save it the database."""
instance = cls(**kwargs)
return instance.save()
def save(self, commit=True):
"""Save the record."""
db.session.add(self)
if commit:
db.session.commit()
return self
class GroceryEnum(enum.Enum):
APPLE = 'APPLE'
BANANA = 'BANANA'
PEAR = 'PEAR'
def __str__(self):
return self.values
class ExampleModel(CustomCreateMixin, db.Model):
id = Column(db.Integer, primary_key=True)
selected_groceries = Column(db.ARRAY(db.Enum(GroceryEnum)))
#, create_constraint=False, native_enum
class ExampleModelSchema(Schema):
id = fields.Int(dump_only=True)
selected_groceries = fields.List(EnumField(GroceryEnum))
Выполнение этого вызывает ошибку:
# from the command line
flask shell
# import the db, model, schema and enum
from filename import db, ExampleModel, ExampleModelSchema, GroceryEnum
# init schema
schema = ExampleModelSchema()
#example input
json_data = {"selected_groceries": ['APPLE']}
# use schema to validate or deserialise
data = schema.load(json_data)
# output of data = {'selected_groceries': [<GroceryEnum.APPLE: 'APPLE'>]}
# try to create - ntoe here you may use the standard methods as well instead of this exttension written by us
ExampleModel.create(**data)
Traceback (most recent call last):
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1247, in _execute_
context
self.dialect.do_execute(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\default.py", line 590, in do_exec
ute
cursor.execute(statement, parameters)
psycopg2.errors.DatatypeMismatch: column "selected_groceries" is of type groceryenum[] but expression is of type text[]
LINE 1: ...T INTO example_model (selected_groceries) VALUES (ARRAY['APP...
^
HINT: You will need to rewrite or cast the expression.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\cygwin64\home\hamis\microservices\microservices\exampleapp\src\modules\main\examplemodule\models.py", line 168, in create
return instance.save()
File "C:\cygwin64\home\hamis\microservices\microservices\exampleapp\src\modules\main\examplemodule\models.py", line 174, in save
db.session.commit()
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\scoping.py", line 162, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1036, in commit
self.transaction.commit()
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\session.py", line 503, in commit
self._prepare_impl()
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\session.py", line 482, in _prepare_i
mpl
self.session.flush()
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\session.py", line 2496, in flush
self._flush(objects)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\session.py", line 2637, in _flush
transaction.rollback(_capture_exception=True)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 68, in __exit
__
compat.raise_(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\util\compat.py", line 178, in raise_
raise exception
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\session.py", line 2597, in _flush
flush_context.execute()
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 422, in execute
rec.execute(self)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 586, in execute
persistence.save_obj(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\orm\persistence.py", line 239, in save_o
bj
_emit_insert_statements(
_insert_statements
result = cached_connections[connection].execute(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 984, in execute
return meth(self, multiparams, params)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\sql\elements.py", line 293, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1097, in _execute_clauseelement
ret = self._execute_context(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1287, in _execute_context
self._handle_dbapi_exception(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1481, in _handle_dbapi_exception
util.raise_(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\util\compat.py", line 178, in raise_
raise exception
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1247, in _execute_context
self.dialect.do_execute(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\default.py", line 590, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DatatypeMismatch) column "selected_groceries" is of type groceryenum[] but expression is of type text[]
LINE 1: ...T INTO example_model (selected_groceries) VALUES (ARRAY['APP...
^
HINT: You will need to rewrite or cast the expression.
[SQL: INSERT INTO example_model (selected_groceries) VALUES (%(selected_groceries)s) RETURNING example_model.id]
[parameters: {'selected_groceries': ['APPLE']}]
(Background on this error at: http://sqlalche.me/e/f405)
Предполагается, что тип не преобразуется / не преобразуется во время преобразования кода вставки, таким образом, пытаясь ввести массив текста вместо заданного Enum.
- Я попытался использовать приведенное ниже без отличается в результате
Column(db.ARRAY(db.Enum(GroceryEnum, create_constraint=False)))
- Я перепробовал множество комбинаций других параметров, и мне не повезло
- Один параметр, который я, возможно, не понял правильно, это
native_enum=False
. При попытке это вызывает другую ошибку, которую я поставил ниже:
Ошибка с native_enum=False
:
Creating tables Boasy Phone Deals Service...
Traceback (most recent call last):
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1247, in _execute_context
self.dialect.do_execute(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\default.py", line 590, in do_execute
cursor.execute(statement, parameters)
psycopg2.errors.InvalidTextRepresentation: malformed array literal: "APPLE"
DETAIL: Array value must start with "{" or dimension information.
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "c:\users\hamis.desktop-u1seum7.000\appdata\local\programs\python\python38\lib\runpy.py", line 193, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\users\hamis.desktop-u1seum7.000\appdata\local\programs\python\python38\lib\runpy.py", line 86, in _run_code
exec(code, run_globals)
File "C:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\Scripts\flask.exe\__main__.py", line 7, in <module>
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\flask\cli.py", line 966, in main
cli.main(prog_name="python -m flask" if as_module else None)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\flask\cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\click\core.py", line 717, in main
rv = self.invoke(ctx)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\click\core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\click\core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\click\core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\click\core.py", line 555, in invoke
return callback(*args, **kwargs)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\click\decorators.py", line 17, in new_func
return f(get_current_context(), *args, **kwargs)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\flask\cli.py", line 426, in decorator
return __ctx.invoke(f, *args, **kwargs)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\click\core.py", line 555, in invoke
return callback(*args, **kwargs)
File "C:\cygwin64\home\hamis\microservices\microservices\exampleapp\src\commands.py", line 25, in reset_database
db.create_all()
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1033, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1025, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\sql\schema.py", line 4320, in create_all
bind._run_visitor(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 2058, in _run_visitor
conn._run_visitor(visitorcallable, element, **kwargs)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1627, in _run_visitor
visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\sql\visitors.py", line 144, in traverse_single
return meth(obj, **kw)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 777, in visit_metadata
self.traverse_single(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\sql\visitors.py", line 144, in traverse_single
return meth(obj, **kw)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 821, in visit_table
self.connection.execute(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 984, in execute
return meth(self, multiparams, params)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 72, in _execute_on_connection
return connection._execute_ddl(self, multiparams, params)
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1041, in _execute_ddl
ret = self._execute_context(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1287, in _execute_context
self._handle_dbapi_exception(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1481, in _handle_dbapi_exception
util.raise_(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\util\compat.py", line 178, in raise_
raise exception
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1247, in _execute_context
self.dialect.do_execute(
File "c:\cygwin64\home\hamis\microservices\microservices\exampleapp\venv\lib\site-packages\sqlalchemy\engine\default.py", line 590, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.DataError: (psycopg2.errors.InvalidTextRepresentation) malformed array literal: "APPLE"
DETAIL: Array value must start with "{" or dimension information.
[SQL:
CREATE TABLE example_model (
id SERIAL NOT NULL,
selected_groceries VARCHAR(6)[],
PRIMARY KEY (id),
CONSTRAINT groceryenum CHECK (selected_groceries IN ('APPLE', 'BANANA', 'PEAR')),
CONSTRAINT groceryenum CHECK (selected_groceries IN ('APPLE', 'BANANA', 'PEAR'))
)
]
(Background on this error at: http://sqlalche.me/e/9h9h)
Ссылки, которые я проверял:
Версии:
Flask==1.1.1
flask-restx==0.1.1
Flask-SQLAlchemy==2.4.1
marshmallow==3.5.1
marshmallow-enum==1.5.1
psycopg2==2.8.4
psycopg2-binary==2.8.4
SQLAlchemy==1.3.16
SQLAlchemy-Utils==0.36.1