无法在SQLAlchemy中从psql-> sqlite3创建create_all()

时间:2019-07-18 12:01:42

标签: python sqlalchemy

我正尝试将PostgressSQL及其所有数据转储到-> SQLite3。

主要思想是创建两个引擎,一个用于PSQL,另一个用于sqlite3。然后我reflect在sqlite引擎上运行psql引擎-并运行create_all(),但随后收到以下错误

2019-07-18 11:41:47,660 INFO sqlalchemy.engine.base.Engine ()
2019-07-18 11:41:47,660 INFO sqlalchemy.engine.base.Engine ROLLBACK
Traceback (most recent call last):
    ... etc ...
sqlalchemy.exc.OperationalError: (pysqlite2.dbapi2.OperationalError) near "(": syntax error [SQL: u"\nCREATE TABLE table1 (\n\tcolumn_id INTEGER DEFAULT nextval('table1_id_seq'::regclass) NOT NULL, \n\t
(Background on this error at: http://sqlalche.me/e/e3q8)

这很有趣,因为SQLAlchemy生成了CREATE TABLE-做到了。问题是什么时候要在create table中执行sqlite3,然后sqlite3将该错误返回给SQLAlchemy-它不理解下面的nextval是什么,并且::是:

column_id INTEGER DEFAULT nextval('table1_id_seq'::regclass) NOT NULL,
column_name VARCHAR(15) DEFAULT 'no-name'::character varying,

我个人甚至不需要这些-因为sqlite将用作快照数据库,但是如何忽略呢?或进行调整?

编辑1-具有特定型号

如果在代码中,我写这样的东西

class Table1(Base):
    __table__ = Table('table1',
                    Base.metadata,
                    Column('column_id', Integer, primary_key=True),
                    Column('column_name', Text, default='no-name'),
                    autoload=True)

工作示例-但我尝试不使用class Table1

做同样的事情
from sqlalchemy import create_engine
from sqlalchemy import Table, Column, Integer, Text
from sqlalchemy.ext.declarative import declarative_base


def review_md_tables(metadata):

    if not metadata.sorted_tables:
        print "-> Tables not found"
        return

    for Table in metadata.sorted_tables:
        print "->", Table.name


print "PSQL database"
psql_url = "postgress://..."
psql_engine = create_engine(psql_url, echo=False)
psql_base = declarative_base(bind=psql_engine)
review_md_tables(psql_base.metadata)

class Table1(psql_base):
    __table__ = Table('table1',
                    pql_base.metadata,
                    Column('column_id', Integer, primary_key=True),
                    Column('column_name', Text, default='no-name'),
                    autoload=True)

review_md_tables(psql_base.metadata)

sqlite_url = "sqlite:////tmp/db.sqlite"
sqlite_enging = create_engine(sqlite_url, echo=False)

# Duplicate PSQL tables -> SQLite
psql_base.metadata.create_all(sqlite_enging)

问题是,我不想开始为数据库中的每个表编写类模型……有什么想法吗?

1 个答案:

答案 0 :(得分:0)

除非有人有更好的主意,否则这是我到目前为止找到的解决方案-逐一删除这些列中的server_default(我们可以使用default定义SQLAlchemy默认值.. < / p>

def remove_defaults_from_tables(metadata):
    for Table in metadata.sorted_tables:
        print "--> Adjusting table: ", Table.name

        # Fixing PSQL unsupported DEFAULT & serial columns
        # https://github.com/sqlalchemy/sqlalchemy/issues/525
        # https://github.com/sqlalchemy/sqlalchemy/issues/1565
        if Table.name in ["table1", "table2"]:
            Table.c.id.server_default = None

因此,应在用metadata填充所有Tables后使用此功能

# This doesn't require pre-defined Models - 
# BUT they will also load those special PSQL variables which SQLAlchemy 
# can't determine later during the `create_all`
Base.metadata.reflect(bind=my_psql_engine, only=["table1", "table2"])
remove_defaults_from_tables(Base.metadata)