Как использовать модели SQLAlchemy для генерации необработанного SQL, который может создавать все таблицы?Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Как использовать модели SQLAlchemy для генерации необработанного SQL, который может создавать все таблицы?

Сообщение Anonymous »

Можно сгенерировать необработанный оператор SQL для создания любой таблицы SQLAlchemy, как показано здесь.
Однако я хотел бы сгенерировать необработанный SQL, который создает все таблицы, а не только одну.< /p>
Предположим, что у меня есть такие таблицы (дизайн этой таблицы не соответствует реальному миру, но он хорошо показывает проблему):

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

import sqlalchemy
from sqlalchemy import Column, Integer, Text, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import CreateTable
from sqlalchemy.dialects import postgresql

engine = sqlalchemy.create_engine('postgresql://postgres:[email protected]:5432/postgres', echo=True)
Base = declarative_base()

class Product(Base):
__tablename__ = "product"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(Text, nullable=True)
user_id = Column(Integer, ForeignKey('user.id'), nullable=True)

class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(Text, nullable=True)
product_id = Column(Integer, ForeignKey('product.id'), nullable=True)

open("create_tables.sql", 'w').close() # to clear the file

for table in Base.metadata.tables.values():
table_sql = str(CreateTable(table).compile(dialect=postgresql.dialect()))
with open("create_tables.sql", "a") as myfile:
myfile.write(table_sql)

Base.metadata.create_all(engine)
(это полная программа, вы можете запускать ее как есть)
В приведенном выше коде вы можете видеть, что я использую для цикл для генерации необработанного SQL:

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

for table in Base.metadata.tables.values():
table_sql = str(CreateTable(table).compile(dialect=postgresql.dialect()))
with open("create_tables.sql", "a") as myfile:
myfile.write(table_sql)
Результирующий файл содержит:

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

CREATE TABLE product (
id SERIAL NOT NULL,
name TEXT,
user_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(user_id) REFERENCES "user" (id)
)

CREATE TABLE "user" (
id SERIAL NOT NULL,
name TEXT,
product_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(product_id) REFERENCES product (id)
)
Но я не могу выполнить этот код SQL, он выдаст ошибку из-за циклической ссылки. (и мне нужно добавить хотя бы несколько ;)

Однако SQLAlchemy может без проблем создавать эти таблицы, когда я использую:

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

Base.metadata.create_all(engine)
При echo=True сгенерированный SQL отображается в журнале:

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

2021-10-18 05:37:24,442 INFO sqlalchemy.engine.Engine select version()
2021-10-18 05:37:24,443 INFO sqlalchemy.engine.Engine [raw sql] {}
2021-10-18 05:37:24,447 INFO sqlalchemy.engine.Engine select current_schema()
2021-10-18 05:37:24,447 INFO sqlalchemy.engine.Engine [raw sql] {}
2021-10-18 05:37:24,449 INFO sqlalchemy.engine.Engine show standard_conforming_strings
2021-10-18 05:37:24,450 INFO sqlalchemy.engine.Engine [raw sql] {}
2021-10-18 05:37:24,454 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2021-10-18 05:37:24,455 INFO sqlalchemy.engine.Engine select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where pg_catalog.pg_table_is_visible(c.oid) and relname=%(name)s
2021-10-18 05:37:24,456 INFO sqlalchemy.engine.Engine [generated in 0.00073s] {'name': 'product'}
2021-10-18 05:37:24,459 INFO sqlalchemy.engine.Engine select relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where pg_catalog.pg_table_is_visible(c.oid) and relname=%(name)s
2021-10-18 05:37:24,460 INFO sqlalchemy.engine.Engine [cached since 0.004542s ago] {'name': 'user'}2021-10-18 05:37:24,463 INFO sqlalchemy.engine.Engine
CREATE TABLE product (
id SERIAL NOT NULL,
name TEXT,
user_id INTEGER,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL,
PRIMARY KEY (id)
)

2021-10-18 05:37:24,464 INFO sqlalchemy.engine.Engine [no key 0.00116s] {}
2021-10-18 05:37:24,480 INFO sqlalchemy.engine.Engine
CREATE TABLE "user" (
id SERIAL NOT NULL,
name TEXT,
product_id INTEGER,
created_at TIMESTAMP WITH TIME ZONE DEFAULT now() NOT NULL,
PRIMARY KEY (id)
)

2021-10-18 05:37:24,481 INFO sqlalchemy.engine.Engine [no key 0.00128s] {}
2021-10-18 05:37:24,494 INFO sqlalchemy.engine.Engine ALTER TABLE product ADD FOREIGN KEY(user_id)
REFERENCES "user" (id)
2021-10-18 05:37:24,495 INFO sqlalchemy.engine.Engine [no key 0.00053s] {}
2021-10-18 05:37:24,497 INFO sqlalchemy.engine.Engine ALTER TABLE "user" ADD FOREIGN KEY(product_id) REFERENCES product (id)
2021-10-18 05:37:24,497 INFO sqlalchemy.engine.Engine [no key 0.00047s] {}
2021-10-18 05:37:24,500 INFO sqlalchemy.engine.Engine COMMIT
Мой вопрос заключается в том, как получить этот SQL, который виден в журнале выше и способен создавать все таблицы за одну транзакцию в виде строки Python (или файла .sql). )?
Я хочу иметь возможность проверить/просмотреть его, а затем применить его (или его часть) вручную к рабочему серверу.

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

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

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

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

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

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

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