Search code examples
sqldatabasesqlalchemyalembic

After upgrade, how to fill new table with values that based on existing values of another table?


I have this table with some data in it:

Name: 
users

Columns:
id (primary key) | name

Rows:
1) 1 | "name 1"
2) 2 | "name 2"
3) 3 | "name 3"

Relationships:
settings

I need to create this table:

Name:
user_settings

Columns:
user_id (primary_key, foreign_key) | some_key

Relationships:
user

Using alembic revision I got this upgrade script:

def upgrade():
    op.create_table('user_settings',
        sa.Column('user_id', sa.Integer(), nullable=False),
        sa.Column('some_key', sa.String(), nullable=True),
        sa.ForeignKeyConstraint(['user_id'], ['users.id']),
        sa.PrimaryKeyConstraint('user_id')
    )

After alembic upgrade it creates an empty user_settings table (as expected). But I need to use settings values for each existing user immediately after upgrade. For example, when I get user value with following SQLAlchemy query:

user = User.query.filter(User.id == id).first()

I should be able to access user settings something like that:

value = user.settings.some_key

But it is not possible right after upgrade because user_settings table is empty.

How to fill new table with mapped values right after upgrade? So that when I run alembic upgrade I should get a table with values, not an empty table:

Name:
user_settings

Columns:
user_id (primary_key, foreign_key) | some_key

Rows:
1) 1 | "default value"
2) 2 | "default value"
3) 3 | "default value"

Relationships:
user

I can think of two approaches:

  1. Manually perform some actions to fill new table.
  2. Don't fill new table and write function something like settings_get_or_create() (which will create new settings for user if settings row for that user don't exists).

There is other approaches? What is best?

I'm using Alembic, SQLAlchemy and SQL database.


Solution

  • Solved using this answer. As it turned out, what i asked for is called "data migration".