Зеркальный SQL Server в DuckDB Локальную базу данных с SQLALCHEMY: ограничение не реализованоPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Зеркальный SQL Server в DuckDB Локальную базу данных с SQLALCHEMY: ограничение не реализовано

Сообщение Anonymous »

Я пытаюсь отразить удаленную базу данных SQL Server в локальную базу данных DuckDB.

Код: Выделить всё

# Connect to remote db
username = "USERNAME"
hostip = "IPADD"
port = "PORT"
dbname = "DBNAME"
user_domain = "USER_DOMAIN"
# See: https://stackoverflow.com/a/58858572/1719931
eng_str = rf"mssql+pymssql://{user_domain}\{username}:{password}@{hostip}/{dbname}"
# Establish connection
engine_remote = create_engine(eng_str, echo=False)
# Test that connection to remote database works
with Session(engine_remote) as session:
print(session.execute(text("SELECT 'hello world'")).fetchall())

# Local db
dbfp = Path("localdb.duckdb")
engine_local = create_engine(f"duckdb:///{dbfp}", echo=False)

# To reflect the metadata of a database with ORM we need the "Automap" extension
# Automap is an extension to the sqlalchemy.ext.declarative system which automatically generates
# mapped classes and relationships from a database schema,
# typically though not necessarily one which is reflected.
# See: https://docs.sqlalchemy.org/en/20/orm/extensions/automap.html
Base = automap_base()

# See ORM documentation on intercepting column definitions: https://docs.sqlalchemy.org/en/20/orm/extensions/automap.html#intercepting-column-definitions
@event.listens_for(Base.metadata, "column_reflect")
def genericize_datatypes(inspector, tablename, column_dict):
# Convert dialect specific column types to SQLAlchemy agnostic types
# See: https://stackoverflow.com/questions/79496414/convert-tinyint-to-int-when-mirroring-microsoft-sql-server-to-local-sqlite-with
# See Core documentation on reflecting with database-agnostic types: https://docs.sqlalchemy.org/en/20/core/reflection.html#reflecting-with-database-agnostic-types
old_type = column_dict['type']
column_dict["type"] = column_dict["type"].as_generic()
# We have to remove collation when mirroring a Microsoft SQL server into SQLite
# See: https://stackoverflow.com/a/59328211/1719931
if getattr(column_dict["type"], "collation", None) is not None:
column_dict["type"].collation = None
# Print debug info
if not isinstance(column_dict['type'], type(old_type)):
print(f"Genericizing `{column_dict['name']}` of type `{str(old_type)}` into `{column_dict['type']}`")

# Load Base with remote DB metadata
Base.prepare(autoload_with=engine_remote)

Base.metadata.create_all(engine_local)
< /code>
Но я получаю эту ошибку: < /p>
---------------------------------------------------------------------------
NotImplementedException                   Traceback (most recent call last)
File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:1964, in Connection._exec_single_context(self, dialect, context, statement, parameters)
1963     if not evt_handled:
-> 1964         self.dialect.do_execute(
1965             cursor, str_statement, effective_parameters, context
1966         )
1968 if self._has_events or self.engine._has_events:

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\default.py:942, in DefaultDialect.do_execute(self, cursor, statement, parameters, context)
941 def do_execute(self, cursor, statement, parameters, context=None):
--> 942     cursor.execute(statement, parameters)

File PYTHONPATH\Lib\site-packages\duckdb_engine\__init__.py:150, in CursorWrapper.execute(self, statement, parameters, context)
149     else:
--> 150         self.__c.execute(statement, parameters)
151 except RuntimeError as e:

NotImplementedException: Not implemented Error: Constraint not implemented!

The above exception was the direct cause of the following exception:

NotSupportedError                         Traceback (most recent call last)
Cell In[25], line 1
----> 1 Base.metadata.create_all(engine_local)

File PYTHONPATH\Lib\site-packages\sqlalchemy\sql\schema.py:5907, in MetaData.create_all(self, bind, tables, checkfirst)
5883 def create_all(
5884     self,
5885     bind: _CreateDropBind,
5886     tables: Optional[_typing_Sequence[Table]] = None,
5887     checkfirst: bool = True,
5888 ) -> None:
5889     """Create all tables stored in this metadata.
5890
5891     Conditional by default, will not attempt to recreate tables already
(...)   5905
5906     """
->  5907     bind._run_ddl_visitor(
5908         ddl.SchemaGenerator, self, checkfirst=checkfirst, tables=tables
5909     )

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:3249, in Engine._run_ddl_visitor(self, visitorcallable, element, **kwargs)
3242 def _run_ddl_visitor(
3243     self,
3244     visitorcallable: Type[Union[SchemaGenerator, SchemaDropper]],
3245     element: SchemaItem,
3246     **kwargs: Any,
3247 ) -> None:
3248     with self.begin() as conn:
-> 3249         conn._run_ddl_visitor(visitorcallable, element, **kwargs)

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:2456, in Connection._run_ddl_visitor(self, visitorcallable, element, **kwargs)
2444 def _run_ddl_visitor(
2445     self,
2446     visitorcallable: Type[Union[SchemaGenerator, SchemaDropper]],
2447     element: SchemaItem,
2448     **kwargs: Any,
2449 ) -> None:
2450     """run a DDL visitor.
2451
2452     This method is only here so that the MockConnection can change the
2453     options given to the visitor so that "checkfirst" is skipped.
2454
2455     """
-> 2456     visitorcallable(self.dialect, self, **kwargs).traverse_single(element)

File PYTHONPATH\Lib\site-packages\sqlalchemy\sql\visitors.py:664, in ExternalTraversal.traverse_single(self, obj, **kw)
662 meth = getattr(v, "visit_%s" % obj.__visit_name__, None)
663 if meth:
--> 664     return meth(obj, **kw)

File PYTHONPATH\Lib\site-packages\sqlalchemy\sql\ddl.py:978, in SchemaGenerator.visit_metadata(self, metadata)
976 for table, fkcs in collection:
977     if table is not None:
--> 978         self.traverse_single(
979             table,
980             create_ok=True,
981             include_foreign_key_constraints=fkcs,
982             _is_metadata_operation=True,
983         )
984     else:
985         for fkc in fkcs:

File PYTHONPATH\Lib\site-packages\sqlalchemy\sql\visitors.py:664, in ExternalTraversal.traverse_single(self, obj, **kw)
662 meth = getattr(v, "visit_%s" % obj.__visit_name__, None)
663 if meth:
--> 664     return meth(obj, **kw)

File PYTHONPATH\Lib\site-packages\sqlalchemy\sql\ddl.py:1016, in SchemaGenerator.visit_table(self, table, create_ok, include_foreign_key_constraints, _is_metadata_operation)
1007 if not self.dialect.supports_alter:
1008     # e.g., don't omit any foreign key constraints
1009     include_foreign_key_constraints = None
1011 CreateTable(
1012     table,
1013     include_foreign_key_constraints=(
1014         include_foreign_key_constraints
1015     ),
-> 1016 )._invoke_with(self.connection)
1018 if hasattr(table, "indexes"):
1019     for index in table.indexes:

File PYTHONPATH\Lib\site-packages\sqlalchemy\sql\ddl.py:314, in ExecutableDDLElement._invoke_with(self, bind)
312 def _invoke_with(self, bind):
313     if self._should_execute(self.target, bind):
--> 314         return bind.execute(self)

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:1416, in Connection.execute(self, statement, parameters, execution_options)
1414     raise exc.ObjectNotExecutableError(statement) from err
1415 else:
-> 1416     return meth(
1417         self,
1418         distilled_parameters,
1419         execution_options or NO_OPTIONS,
1420     )

File PYTHONPATH\Lib\site-packages\sqlalchemy\sql\ddl.py:180, in ExecutableDDLElement._execute_on_connection(self, connection, distilled_params, execution_options)
177 def _execute_on_connection(
178     self, connection, distilled_params, execution_options
179 ):
--> 180     return connection._execute_ddl(
181         self, distilled_params, execution_options
182     )

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:1527, in Connection._execute_ddl(self, ddl, distilled_parameters, execution_options)
1522 dialect = self.dialect
1524 compiled = ddl.compile(
1525     dialect=dialect, schema_translate_map=schema_translate_map
1526 )
->  1527 ret = self._execute_context(
1528     dialect,
1529     dialect.execution_ctx_cls._init_ddl,
1530     compiled,
1531     None,
1532     exec_opts,
1533     compiled,
1534 )
1535 if self._has_events or self.engine._has_events:
1536     self.dispatch.after_execute(
1537         self,
1538         ddl,
(...)   1542         ret,
1543     )

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:1843, in Connection._execute_context(self, dialect, constructor, statement, parameters, execution_options, *args, **kw)
1841     return self._exec_insertmany_context(dialect, context)
1842 else:
-> 1843     return self._exec_single_context(
1844         dialect, context, statement, parameters
1845     )

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:1983, in Connection._exec_single_context(self, dialect, context, statement, parameters)
1980     result = context._setup_result_proxy()
1982 except BaseException as e:
-> 1983     self._handle_dbapi_exception(
1984         e, str_statement, effective_parameters, cursor, context
1985     )
1987 return result

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:2352, in Connection._handle_dbapi_exception(self, e, statement, parameters, cursor, context, is_sub_exec)
2350 elif should_wrap:
2351     assert sqlalchemy_exception is not None
-> 2352     raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
2353 else:
2354     assert exc_info[1] is not None

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\base.py:1964, in Connection._exec_single_context(self, dialect, context, statement, parameters)
1962                 break
1963     if not evt_handled:
-> 1964         self.dialect.do_execute(
1965             cursor, str_statement, effective_parameters, context
1966         )
1968 if self._has_events or self.engine._has_events:
1969     self.dispatch.after_cursor_execute(
1970         self,
1971         cursor,
(...)   1975         context.executemany,
1976     )

File PYTHONPATH\Lib\site-packages\sqlalchemy\engine\default.py:942, in DefaultDialect.do_execute(self, cursor, statement, parameters, context)
941 def do_execute(self, cursor, statement, parameters, context=None):
--> 942     cursor.execute(statement, parameters)

File PYTHONPATH\Lib\site-packages\duckdb_engine\__init__.py:150, in CursorWrapper.execute(self, statement, parameters, context)
148         self.__c.execute(statement)
149     else:
--> 150         self.__c.execute(statement, parameters)
151 except RuntimeError as e:
152     if e.args[0].startswith("Not implemented Error"):

NotSupportedError: (duckdb.duckdb.NotImplementedException) Not implemented Error: Constraint not implemented!
[SQL:
CREATE TABLE sysdiagrams (
name VARCHAR(128) NOT NULL,
principal_id INTEGER NOT NULL,
diagram_id INTEGER GENERATED BY DEFAULT AS IDENTITY (INCREMENT BY 1 START WITH 1),
version INTEGER,
definition BYTEA,
CONSTRAINT "PK__sysdiagr__C2B05B613750874A" PRIMARY KEY (diagram_id)
)

]
(Background on this error at: https://sqlalche.me/e/20/tw8g)
Похоже, что ограничение первичного ключа не реализуется в DuckDB?>

Подробнее здесь: https://stackoverflow.com/questions/795 ... -not-imple
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»