Explore all Data Migration open source software, libraries, packages, source code, cloud functions and APIs.

Popular New Releases in Data Migration

gh-ost

GA release v1.1.4

migrations

3.5.0

phinx

0.12.10

goose

v3.5.3

mara-pipelines

Version 3.1.1

Popular Libraries in Data Migration

gh-ost

by github doticongodoticon

star image 9676 doticonMIT

GitHub's Online Schema Migrations for MySQL

pentaho-kettle

by pentaho doticonjavadoticon

star image 5719 doticonApache-2.0

Pentaho Data Integration ( ETL ) a.k.a Kettle

ts-migrate

by airbnb doticontypescriptdoticon

star image 4329 doticonMIT

A tool to help migrate JavaScript code quickly and conveniently to TypeScript

migrations

by doctrine doticonphpdoticon

star image 4309 doticonMIT

Doctrine Database Migrations Library

phinx

by cakephp doticonphpdoticon

star image 4266 doticonMIT

PHP Database Migrations for Everyone

migrations-generator

by Xethron doticonphpdoticon

star image 3229 doticonMIT

Laravel Migrations Generator: Automatically generate your migrations from an existing database schema.

rudder-server

by rudderlabs doticongodoticon

star image 3067 doticonAGPL-3.0

Privacy and Security focused Segment-alternative, in Golang and React

goose

by pressly doticongodoticon

star image 2481 doticonNOASSERTION

A database migration tool. Supports SQL migrations and Go functions.

migra

by djrobstep doticonpythondoticon

star image 2441 doticonUnlicense

Like diff but for PostgreSQL schemas

Trending New libraries in Data Migration

laravel-migrations-generator

by kitloong doticonphpdoticon

star image 924 doticonMIT

Laravel Migrations Generator: Automatically generate your migrations from an existing database schema.

deno-nessie

by halvardssm doticontypescriptdoticon

star image 471 doticonMIT

A modular Deno library for PostgreSQL, MySQL, MariaDB and SQLite migrations

aerich

by tortoise doticonpythondoticon

star image 450 doticonApache-2.0

A database migrations tool for TortoiseORM, ready to production.

django-upgrade

by adamchainz doticonpythondoticon

star image 313 doticonMIT

Automatically upgrade your Django projects.

laravel-migration-generator

by bennett-treptow doticonphpdoticon

star image 287 doticonMIT

Generate migrations from existing database structures

almalinux-deploy

by AlmaLinux doticonshelldoticon

star image 145 doticonGPL-3.0

EL to AlmaLinux migration tool.

etl

by flow-php doticonphpdoticon

star image 124 doticonMIT

PHP - ETL (Extract Transform Load) data processing library

ETL-pipeline

by renatootescu doticonpythondoticon

star image 105 doticonMIT

Educational project on how to build an ETL (Extract, Transform, Load) data pipeline, orchestrated with Airflow.

data-story

by ajthinking doticoncssdoticon

star image 95 doticon

A visual process builder

Top Authors in Data Migration

1

fusionjs

15 Libraries

star icon840

2

blockchain-etl

6 Libraries

star icon43

3

thehyve

4 Libraries

star icon22

4

deprecated-packages

4 Libraries

star icon38

5

contributte

4 Libraries

star icon70

6

scriptella

3 Libraries

star icon115

7

OHDSI

3 Libraries

star icon55

8

canjs

3 Libraries

star icon18

9

mara

3 Libraries

star icon2039

10

aa900031

3 Libraries

star icon11

1

15 Libraries

star icon840

2

6 Libraries

star icon43

3

4 Libraries

star icon22

4

4 Libraries

star icon38

5

4 Libraries

star icon70

6

3 Libraries

star icon115

7

3 Libraries

star icon55

8

3 Libraries

star icon18

9

3 Libraries

star icon2039

10

3 Libraries

star icon11

Trending Kits in Data Migration

No Trending Kits are available at this moment for Data Migration

Trending Discussions on Data Migration

Download DML and DDL sql from Teradata using python

Cosmos DB REPLACE strings in nested Object

FastAPI refuses to let me create a mongoengine document

How to deal with missing columns on old data migrations?

Alternative Syntax or Logic for AngularFireStore Update?

How to maintain a table of all proxy models in Django?

How to abandon a manual Room migration script, and fall back to destructive migration?

Copy SQL Server Scheduled Jobs to Oracle Scheduler

Using SchemaCrawler API to get Weak/Implied Relationships

MySQL idempotent version of add column failing

QUESTION

Download DML and DDL sql from Teradata using python

Asked 2022-Mar-23 at 11:14

What approach should I follow to download DDL, DML and Stored Procedures from the teradata database using python.

I have created the sample code but what is the approach to download these sql files for data migration process.

1udaExec = teradata.UdaExec(appName="HelloWorld", version="1.0",logConsole=False)
2session = udaExec.connect(method="odbc", system="xxx",username="xxx", password="xxx");
3for row in session.execute("show tables {} > {}".format(tables, export_tables)):
4     print(row)
5

Unlike MSSQL which had mssql-scripter to download .sql files, does teradata provide any such option to download. Also, does it provide support to download sequences, views and procedures ?

For the Schema Migration process, what should be the best approach to download these files from the teradata as a source ?

ANSWER

Answered 2022-Mar-23 at 11:14

Happy to share that I got the solution for this approach. In order to get the files in sql format use the given code to extract DDL and DML Code.

The given code is for sample database dbc.

1udaExec = teradata.UdaExec(appName="HelloWorld", version="1.0",logConsole=False)
2session = udaExec.connect(method="odbc", system="xxx",username="xxx", password="xxx");
3for row in session.execute("show tables {} > {}".format(tables, export_tables)):
4     print(row)
5with teradatasql.connect(host='enter_host_ip', user='---', password='---') as connect:
6#get the table name and database name in csv file using select statement
7df = pd.read_csv("result.csv", index_col=None)
8for tables_name in df['TableName']:
9    query = "SHOW TABLE DBC."+ tables_name
10    try:
11        df = pd.read_sql(query, connect)
12        df1 = df['Request Text'][0]
13        writePath = "C:\\Users\\SQL\\"+tables_name+".sql"
14        with open(writePath, 'a') as f:
15            dfAsString = df1
16            f.write(dfAsString)
17    except Exception as e1:
18        print(tables_name)            
19        pass
20

Note : Out of 192 tables I was able to get DDL/DML scripts for 189 tables. For tables perform manual intervention.

Source https://stackoverflow.com/questions/70331340

QUESTION

Cosmos DB REPLACE strings in nested Object

Asked 2022-Mar-22 at 15:09

I'm using the Cosmos Data migration tool to migrate data between environments. During my migration, I need to update the hostname of the website in the data. I was able to do this pretty easily with a query like this with the top level object data:

1SELECT Farms["name"], Farms["farmerInfo"], REPLACE(Farms["websiteLink"], "thiswebsite", "newHostName") AS websiteLink FROM Farms
2

My Cosmos DB data is structured like (data is just for the example):

1SELECT Farms["name"], Farms["farmerInfo"], REPLACE(Farms["websiteLink"], "thiswebsite", "newHostName") AS websiteLink FROM Farms
2{  
3    "name": "Red's Farm",
4    "websiteLink": "www.thiswebsite.com/goats/",
5    "farmerInfo": {  
6        "name":       "Bob",   
7        "websiteLink":      "www.thiswebsite.com/goats/",   
8        "hasGoats":    true,  
9        "numGoats":    17
10
11    }  
12}  
13

I don't actually need to modify any of the top level data. The data I need to modify is within the "farmerInfo" object. I've tried a few things but I've had no luck. How can I replace a string in this object using the SQL api?

I want the data to look like this after the migration:

1SELECT Farms["name"], Farms["farmerInfo"], REPLACE(Farms["websiteLink"], "thiswebsite", "newHostName") AS websiteLink FROM Farms
2{  
3    "name": "Red's Farm",
4    "websiteLink": "www.thiswebsite.com/goats/",
5    "farmerInfo": {  
6        "name":       "Bob",   
7        "websiteLink":      "www.thiswebsite.com/goats/",   
8        "hasGoats":    true,  
9        "numGoats":    17
10
11    }  
12}  
13{  
14        "name": "Red's Farm",
15        "websiteLink": "www.thiswebsite.com/goats/",
16        "farmerInfo": {  
17            "name":       "Bob",   
18            "websiteLink":      "www.newHostName.com/goats/",  <--- Updated data
19            "hasGoats":    true,   
20            "numGoats":    17
21 
22        }  
23    }  
24

ANSWER

Answered 2022-Mar-22 at 15:09

You can use a SELECT statement in your SELECT statement to build up the sub objects. As example:

1SELECT Farms["name"], Farms["farmerInfo"], REPLACE(Farms["websiteLink"], "thiswebsite", "newHostName") AS websiteLink FROM Farms
2{  
3    "name": "Red's Farm",
4    "websiteLink": "www.thiswebsite.com/goats/",
5    "farmerInfo": {  
6        "name":       "Bob",   
7        "websiteLink":      "www.thiswebsite.com/goats/",   
8        "hasGoats":    true,  
9        "numGoats":    17
10
11    }  
12}  
13{  
14        "name": "Red's Farm",
15        "websiteLink": "www.thiswebsite.com/goats/",
16        "farmerInfo": {  
17            "name":       "Bob",   
18            "websiteLink":      "www.newHostName.com/goats/",  <--- Updated data
19            "hasGoats":    true,   
20            "numGoats":    17
21 
22        }  
23    }  
24SELECT 
25    c.name,
26    c.websiteLink,
27    (
28        SELECT 
29            c.farmerInfo.name, 
30            REPLACE(c.farmerInfo.websiteLink, "thiswebsite", "newHostName") AS websiteLink
31    ) AS farmerInfo
32FROM c
33

Source https://stackoverflow.com/questions/71566416

QUESTION

FastAPI refuses to let me create a mongoengine document

Asked 2022-Mar-10 at 02:01

I have FastAPI Python application with routes that operate on a MongoDB instance. The connection works fine, and I can query documents for my GET endpoints, but creating a new document from within FastAPI seems impossible.

I consistently get:

You have not defined a default connection

I have a standalone script that handles some data migration tasks and it uses the exact same DB class and Document models that the FastAPI app does, and that script is able to save documents to mongo perfectly fine. There is no difference in how the DB object is instantiated between the API and the script.

The DB class:

1from os import getenv
2
3from mongoengine import connect
4from pymongo import MongoClient
5from pymongo.errors import ServerSelectionTimeoutError
6
7class Mongo:
8
9    @property
10    def target_db(self):
11        return 'some_db'
12
13    @property
14    def uri(self) -> str:
15        env_uri = getenv('MONGODB', None)
16        if env_uri is None:
17            raise DBError('MONGODB environment variable missing')
18        return env_uri.strip()
19
20    def connect(self) -> MongoClient:
21        try:
22            return connect(host=self.uri, db=self.target_db, alias=self.target_db)
23        except ServerSelectionTimeoutError as e:
24            raise ServerSelectionTimeoutError(e)
25

All of my DB models have meta attributes defining exactly what DB and collection to use:

1from os import getenv
2
3from mongoengine import connect
4from pymongo import MongoClient
5from pymongo.errors import ServerSelectionTimeoutError
6
7class Mongo:
8
9    @property
10    def target_db(self):
11        return 'some_db'
12
13    @property
14    def uri(self) -> str:
15        env_uri = getenv('MONGODB', None)
16        if env_uri is None:
17            raise DBError('MONGODB environment variable missing')
18        return env_uri.strip()
19
20    def connect(self) -> MongoClient:
21        try:
22            return connect(host=self.uri, db=self.target_db, alias=self.target_db)
23        except ServerSelectionTimeoutError as e:
24            raise ServerSelectionTimeoutError(e)
25class Thing(Document):
26    meta = {'db_alias': 'some_db',
27            'collection': 'things'}
28

Queries on existing documents succeed inside of a route definition:

1from os import getenv
2
3from mongoengine import connect
4from pymongo import MongoClient
5from pymongo.errors import ServerSelectionTimeoutError
6
7class Mongo:
8
9    @property
10    def target_db(self):
11        return 'some_db'
12
13    @property
14    def uri(self) -> str:
15        env_uri = getenv('MONGODB', None)
16        if env_uri is None:
17            raise DBError('MONGODB environment variable missing')
18        return env_uri.strip()
19
20    def connect(self) -> MongoClient:
21        try:
22            return connect(host=self.uri, db=self.target_db, alias=self.target_db)
23        except ServerSelectionTimeoutError as e:
24            raise ServerSelectionTimeoutError(e)
25class Thing(Document):
26    meta = {'db_alias': 'some_db',
27            'collection': 'things'}
28results = Thing.objects.filter(**query)
29# This returns things that I can iterate over
30

Document creation fails inside of a route definition:

1from os import getenv
2
3from mongoengine import connect
4from pymongo import MongoClient
5from pymongo.errors import ServerSelectionTimeoutError
6
7class Mongo:
8
9    @property
10    def target_db(self):
11        return 'some_db'
12
13    @property
14    def uri(self) -> str:
15        env_uri = getenv('MONGODB', None)
16        if env_uri is None:
17            raise DBError('MONGODB environment variable missing')
18        return env_uri.strip()
19
20    def connect(self) -> MongoClient:
21        try:
22            return connect(host=self.uri, db=self.target_db, alias=self.target_db)
23        except ServerSelectionTimeoutError as e:
24            raise ServerSelectionTimeoutError(e)
25class Thing(Document):
26    meta = {'db_alias': 'some_db',
27            'collection': 'things'}
28results = Thing.objects.filter(**query)
29# This returns things that I can iterate over
30new_thing = Thing(**creation_args)
31new_thing.save()
32

Error:

1from os import getenv
2
3from mongoengine import connect
4from pymongo import MongoClient
5from pymongo.errors import ServerSelectionTimeoutError
6
7class Mongo:
8
9    @property
10    def target_db(self):
11        return 'some_db'
12
13    @property
14    def uri(self) -> str:
15        env_uri = getenv('MONGODB', None)
16        if env_uri is None:
17            raise DBError('MONGODB environment variable missing')
18        return env_uri.strip()
19
20    def connect(self) -> MongoClient:
21        try:
22            return connect(host=self.uri, db=self.target_db, alias=self.target_db)
23        except ServerSelectionTimeoutError as e:
24            raise ServerSelectionTimeoutError(e)
25class Thing(Document):
26    meta = {'db_alias': 'some_db',
27            'collection': 'things'}
28results = Thing.objects.filter(**query)
29# This returns things that I can iterate over
30new_thing = Thing(**creation_args)
31new_thing.save()
32mongoengine.connection.ConnectionFailure: You have not defined a default connection
33

What does that even mean? I know that I'm connected because I can query the db.

How is it possible that I can successfully query documents from Mongo but not save them? Every suggestion I have seen online points to not having defined a db or alias in the call to mongoengine.connect, but I clearly am in my Mongo object, and even if that were true, surely I wouldn't be able to retrieve documents from the db collection...

ANSWER

Answered 2022-Mar-10 at 02:01

The mongoengine Document models had malformatted meta attributes...

1from os import getenv
2
3from mongoengine import connect
4from pymongo import MongoClient
5from pymongo.errors import ServerSelectionTimeoutError
6
7class Mongo:
8
9    @property
10    def target_db(self):
11        return 'some_db'
12
13    @property
14    def uri(self) -> str:
15        env_uri = getenv('MONGODB', None)
16        if env_uri is None:
17            raise DBError('MONGODB environment variable missing')
18        return env_uri.strip()
19
20    def connect(self) -> MongoClient:
21        try:
22            return connect(host=self.uri, db=self.target_db, alias=self.target_db)
23        except ServerSelectionTimeoutError as e:
24            raise ServerSelectionTimeoutError(e)
25class Thing(Document):
26    meta = {'db_alias': 'some_db',
27            'collection': 'things'}
28results = Thing.objects.filter(**query)
29# This returns things that I can iterate over
30new_thing = Thing(**creation_args)
31new_thing.save()
32mongoengine.connection.ConnectionFailure: You have not defined a default connection
33class Accounts(Document):
34    meta = {'db_alias': 'some_db',
35            'collection': 'things'}
36

Solution:db_alias​ needed to be changed to ​db​.

I didn't find this through documentation, and definitely not through the extremely unhelpful error messages. I just tried it on a whim. Now everything works using the FastAPI framework.

Source https://stackoverflow.com/questions/71403415

QUESTION

How to deal with missing columns on old data migrations?

Asked 2022-Mar-09 at 02:13

I want to add a new column to a django model. However, I have a past data migration that creates an object of this model, which now doesn't work because the column didn't exist at the time of that migration.

i.e. my model is:

1class MyModel(models.Model):
2    name = models.CharField()
3    foo = models.IntegerField()  # <-- I want to add this column
4

however my old migration is this:

1class MyModel(models.Model):
2    name = models.CharField()
3    foo = models.IntegerField()  # <-- I want to add this column
4def add_my_model(apps, schema_editor):
5    MyModel.objects.create(name="blah")
6
7class Migration(migrations.Migration):
8    # ...
9    operations = [
10        migrations.RunPython(add_my_model),
11    ]
12

And when I try to run migrations on a fresh db, this migration fails with an error similar to this:

1class MyModel(models.Model):
2    name = models.CharField()
3    foo = models.IntegerField()  # <-- I want to add this column
4def add_my_model(apps, schema_editor):
5    MyModel.objects.create(name="blah")
6
7class Migration(migrations.Migration):
8    # ...
9    operations = [
10        migrations.RunPython(add_my_model),
11    ]
12query = 'INSERT INTO "my_model" ("name", "foo") VALUES (?, ?)'
13params = ['blah', None]
14
15...
16
17E       sqlite3.OperationalError: table my_model has no column named foo
18

What's the best way to deal with this situation?

ANSWER

Answered 2022-Mar-09 at 02:13

This is explained in Django documentation:

1class MyModel(models.Model):
2    name = models.CharField()
3    foo = models.IntegerField()  # <-- I want to add this column
4def add_my_model(apps, schema_editor):
5    MyModel.objects.create(name="blah")
6
7class Migration(migrations.Migration):
8    # ...
9    operations = [
10        migrations.RunPython(add_my_model),
11    ]
12query = 'INSERT INTO "my_model" ("name", "foo") VALUES (?, ?)'
13params = ['blah', None]
14
15...
16
17E       sqlite3.OperationalError: table my_model has no column named foo
18def combine_names(apps, schema_editor):
19    # We can't import the Person model directly as it may be a newer
20    # version than this migration expects. We use the historical version.
21    Person = apps.get_model('yourappname', 'Person')
22

basically instead of directly importing MyModel you should be doing something like

1class MyModel(models.Model):
2    name = models.CharField()
3    foo = models.IntegerField()  # <-- I want to add this column
4def add_my_model(apps, schema_editor):
5    MyModel.objects.create(name="blah")
6
7class Migration(migrations.Migration):
8    # ...
9    operations = [
10        migrations.RunPython(add_my_model),
11    ]
12query = 'INSERT INTO "my_model" ("name", "foo") VALUES (?, ?)'
13params = ['blah', None]
14
15...
16
17E       sqlite3.OperationalError: table my_model has no column named foo
18def combine_names(apps, schema_editor):
19    # We can't import the Person model directly as it may be a newer
20    # version than this migration expects. We use the historical version.
21    Person = apps.get_model('yourappname', 'Person')
22def add_my_model(apps, schema_editor):
23    MyModel = apps.get_model('yourappname', 'MyModel')
24    MyModel.objects.create(name="blah")
25

Source https://stackoverflow.com/questions/71403555

QUESTION

Alternative Syntax or Logic for AngularFireStore Update?

Asked 2022-Mar-07 at 12:45

I would like to ask for alternative ways to implement Update data in firestore inside a component ts.

Normally I would use a service and subscribe thru it, however, subscribing and using the service became too laggy and our app crashes since our data team injected around 20k+ records due to data migration.

Normally I do the following the old way:

1
2Via Service:
3
4
5import { Injectable } from '@angular/core';
6import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
7import { Observable } from 'rxjs';
8import {map } from 'rxjs/operators';
9
10@Injectable({
11  providedIn: 'root'
12})
13
14export class CustomerService {
15  customerCollection: AngularFirestoreCollection <Customer>;
16  customerDoc: AngularFirestoreDocument <Customer>;
17  customers: Observable<Customer[]>;
18
19   constructor(
20    public angularFireStore: AngularFirestore
21
22  ) 
23  {}
24
25    getCustomer() {
26    this.customerCollection = this.angularFireStore.collection('customer');
27    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes => {
28      return changes.map( a => {
29        const data = a.payload.doc.data() as Customer;
30        data.id=a.payload.doc.id;
31        return data;
32      })
33
34    }))
35    return this.customers;
36  }
37
38  addCustomer(customerAdd:Customer) {
39    this.customerCollection.add(customerAdd);
40  };
41
42  updateCustomer(custcol : Customer) {
43    this.customerDoc = this.angularFireStore.doc(`customer/${custcol.id}`);
44    this.customerDoc.update(custcol);
45  }
46
47
48}
49
50

Normally in my Component TS Old Code, I just usually put the update on a function like this.

1
2Via Service:
3
4
5import { Injectable } from '@angular/core';
6import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
7import { Observable } from 'rxjs';
8import {map } from 'rxjs/operators';
9
10@Injectable({
11  providedIn: 'root'
12})
13
14export class CustomerService {
15  customerCollection: AngularFirestoreCollection <Customer>;
16  customerDoc: AngularFirestoreDocument <Customer>;
17  customers: Observable<Customer[]>;
18
19   constructor(
20    public angularFireStore: AngularFirestore
21
22  ) 
23  {}
24
25    getCustomer() {
26    this.customerCollection = this.angularFireStore.collection('customer');
27    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes => {
28      return changes.map( a => {
29        const data = a.payload.doc.data() as Customer;
30        data.id=a.payload.doc.id;
31        return data;
32      })
33
34    }))
35    return this.customers;
36  }
37
38  addCustomer(customerAdd:Customer) {
39    this.customerCollection.add(customerAdd);
40  };
41
42  updateCustomer(custcol : Customer) {
43    this.customerDoc = this.angularFireStore.doc(`customer/${custcol.id}`);
44    this.customerDoc.update(custcol);
45  }
46
47
48}
49
50 customerList: customerModel[];
51 customerDetails : customerModel;
52 customerName: any;
53 
54 addCustomer : Customer ={
55    customerNo: '',
56    customerAccountNo: '',
57    customerName: '',
58    customerAddress: '',
59    customerContactNo: '',
60    customerEmail: ''
61
62  };
63
64ngOnInit(): void {
65 this.customerService.getCustomer().subscribe( customerObservable => {
66 this.customerList = customerObservable});
67}
68
69
70add() {
71 this.addCustomer.customerName = this.customerName //(input comes from ngModel btw)
72 this.customerCollection.add(this.addCustomer);
73}
74
75update(){
76 this.customerDetails.customerName = this.customerName //(input comes from ngModel btw)
77 this.customerService.UpdateCustomer(this.customerDetails)
78}
79

This works properly and smoothly when we only have 6000+ records, but as stated above after injecting additional records loading and even updating become laggy.

Searching thru solutions, we stop using the service, and put everything inside the component instead , I manage to implement the Query (but just ValueChanges, I believe in order to update I should use SnapshotChanges) and Adding, however there's very minimal or no documentation at all for the Update even on the official AngularFireStore Documentation, that's why I'm struggling for the correct syntax/logic for this one.

Here's my updated Component TS Code

1
2Via Service:
3
4
5import { Injectable } from '@angular/core';
6import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
7import { Observable } from 'rxjs';
8import {map } from 'rxjs/operators';
9
10@Injectable({
11  providedIn: 'root'
12})
13
14export class CustomerService {
15  customerCollection: AngularFirestoreCollection <Customer>;
16  customerDoc: AngularFirestoreDocument <Customer>;
17  customers: Observable<Customer[]>;
18
19   constructor(
20    public angularFireStore: AngularFirestore
21
22  ) 
23  {}
24
25    getCustomer() {
26    this.customerCollection = this.angularFireStore.collection('customer');
27    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes => {
28      return changes.map( a => {
29        const data = a.payload.doc.data() as Customer;
30        data.id=a.payload.doc.id;
31        return data;
32      })
33
34    }))
35    return this.customers;
36  }
37
38  addCustomer(customerAdd:Customer) {
39    this.customerCollection.add(customerAdd);
40  };
41
42  updateCustomer(custcol : Customer) {
43    this.customerDoc = this.angularFireStore.doc(`customer/${custcol.id}`);
44    this.customerDoc.update(custcol);
45  }
46
47
48}
49
50 customerList: customerModel[];
51 customerDetails : customerModel;
52 customerName: any;
53 
54 addCustomer : Customer ={
55    customerNo: '',
56    customerAccountNo: '',
57    customerName: '',
58    customerAddress: '',
59    customerContactNo: '',
60    customerEmail: ''
61
62  };
63
64ngOnInit(): void {
65 this.customerService.getCustomer().subscribe( customerObservable => {
66 this.customerList = customerObservable});
67}
68
69
70add() {
71 this.addCustomer.customerName = this.customerName //(input comes from ngModel btw)
72 this.customerCollection.add(this.addCustomer);
73}
74
75update(){
76 this.customerDetails.customerName = this.customerName //(input comes from ngModel btw)
77 this.customerService.UpdateCustomer(this.customerDetails)
78}
79import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
80import { Observable} from 'rxjs'; 
81import { Customer } from '../../models/customer.model';
82
83
84@Component({
85  selector: 'app-add-client',
86  templateUrl: './add-client.component.html',
87  styleUrls: ['./add-client.component.scss']
88})
89export class AddClientComponent implements OnInit {
90
91 private customerCollection: AngularFirestoreCollection<Customer>
92 private customerDocs: AngularFirestoreDocument<Customer>
93 customers: Observable<Customer[]>
94  
95 constructor(
96    public afs: AngularFirestore
97  ) { 
98    this.customerCollection = this.afs.collection<Customer>('customer')
99    this.customers = this.customerCollection.valueChanges();
100  }
101 customerList: Customer[];
102 customerDetails: Customer;
103
104 addCustomer : Customer ={
105    customerNo: '',
106    customerAccountNo: '',
107    customerName: '',
108    customerAddress: '',
109    customerContactNo: '',
110    customerEmail: ''
111 
112  };
113
114queryCustomer() {
115    
116    this.customerCollection = this.afs.collection('customer',
117    ref => ref
118    .orderBy('customerName')
119    .startAt(this.query)
120    .endAt(this.query + "\uf8ff"));
121    this.customers = this.customerCollection.valueChanges();
122    this.customers.subscribe(
123     (data) => (this.customerList = (data)));
124  }
125
126add() {
127  this.addCustomer.customerName = this.customerName;
128  this.customerCollection.add(this.addCustomer);
129}
130
131queryCustomer() {
132    
133    this.customerCollection = this.afs.collection('customer',
134    ref => ref
135    .orderBy('customerName')
136    .startAt(this.query)
137    .endAt(this.query + "\uf8ff"));
138    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes =>{
139        return changes.map(a =>{
140        const data=a.payload.doc.data() as depositModel;
141        data.id=a.payload.doc.id;
142        return data;
143       });
144      }
145    ));
146    this.customers.subscribe(
147     (data) => (this.customerList = (data)));
148  }
149
150
151}
152

I did the following attempts, but somehow they don't work

1
2Via Service:
3
4
5import { Injectable } from '@angular/core';
6import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
7import { Observable } from 'rxjs';
8import {map } from 'rxjs/operators';
9
10@Injectable({
11  providedIn: 'root'
12})
13
14export class CustomerService {
15  customerCollection: AngularFirestoreCollection <Customer>;
16  customerDoc: AngularFirestoreDocument <Customer>;
17  customers: Observable<Customer[]>;
18
19   constructor(
20    public angularFireStore: AngularFirestore
21
22  ) 
23  {}
24
25    getCustomer() {
26    this.customerCollection = this.angularFireStore.collection('customer');
27    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes => {
28      return changes.map( a => {
29        const data = a.payload.doc.data() as Customer;
30        data.id=a.payload.doc.id;
31        return data;
32      })
33
34    }))
35    return this.customers;
36  }
37
38  addCustomer(customerAdd:Customer) {
39    this.customerCollection.add(customerAdd);
40  };
41
42  updateCustomer(custcol : Customer) {
43    this.customerDoc = this.angularFireStore.doc(`customer/${custcol.id}`);
44    this.customerDoc.update(custcol);
45  }
46
47
48}
49
50 customerList: customerModel[];
51 customerDetails : customerModel;
52 customerName: any;
53 
54 addCustomer : Customer ={
55    customerNo: '',
56    customerAccountNo: '',
57    customerName: '',
58    customerAddress: '',
59    customerContactNo: '',
60    customerEmail: ''
61
62  };
63
64ngOnInit(): void {
65 this.customerService.getCustomer().subscribe( customerObservable => {
66 this.customerList = customerObservable});
67}
68
69
70add() {
71 this.addCustomer.customerName = this.customerName //(input comes from ngModel btw)
72 this.customerCollection.add(this.addCustomer);
73}
74
75update(){
76 this.customerDetails.customerName = this.customerName //(input comes from ngModel btw)
77 this.customerService.UpdateCustomer(this.customerDetails)
78}
79import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
80import { Observable} from 'rxjs'; 
81import { Customer } from '../../models/customer.model';
82
83
84@Component({
85  selector: 'app-add-client',
86  templateUrl: './add-client.component.html',
87  styleUrls: ['./add-client.component.scss']
88})
89export class AddClientComponent implements OnInit {
90
91 private customerCollection: AngularFirestoreCollection<Customer>
92 private customerDocs: AngularFirestoreDocument<Customer>
93 customers: Observable<Customer[]>
94  
95 constructor(
96    public afs: AngularFirestore
97  ) { 
98    this.customerCollection = this.afs.collection<Customer>('customer')
99    this.customers = this.customerCollection.valueChanges();
100  }
101 customerList: Customer[];
102 customerDetails: Customer;
103
104 addCustomer : Customer ={
105    customerNo: '',
106    customerAccountNo: '',
107    customerName: '',
108    customerAddress: '',
109    customerContactNo: '',
110    customerEmail: ''
111 
112  };
113
114queryCustomer() {
115    
116    this.customerCollection = this.afs.collection('customer',
117    ref => ref
118    .orderBy('customerName')
119    .startAt(this.query)
120    .endAt(this.query + "\uf8ff"));
121    this.customers = this.customerCollection.valueChanges();
122    this.customers.subscribe(
123     (data) => (this.customerList = (data)));
124  }
125
126add() {
127  this.addCustomer.customerName = this.customerName;
128  this.customerCollection.add(this.addCustomer);
129}
130
131queryCustomer() {
132    
133    this.customerCollection = this.afs.collection('customer',
134    ref => ref
135    .orderBy('customerName')
136    .startAt(this.query)
137    .endAt(this.query + "\uf8ff"));
138    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes =>{
139        return changes.map(a =>{
140        const data=a.payload.doc.data() as depositModel;
141        data.id=a.payload.doc.id;
142        return data;
143       });
144      }
145    ));
146    this.customers.subscribe(
147     (data) => (this.customerList = (data)));
148  }
149
150
151}
152
153update() {
154 
155  this.customerDocs = this.angularFirestore.doc(`jobOrders/${customerDetails.id}`);
156  this.customerDocs.Update(customerDetails);
157
158}
159
160
161

I'm really new to this kind of implementation and hopefully, someone could help me on this one. Thank you.

ANSWER

Answered 2022-Mar-07 at 12:45

As mentioned in the example1 and example2, update can be done as :

Example1 :

1
2Via Service:
3
4
5import { Injectable } from '@angular/core';
6import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
7import { Observable } from 'rxjs';
8import {map } from 'rxjs/operators';
9
10@Injectable({
11  providedIn: 'root'
12})
13
14export class CustomerService {
15  customerCollection: AngularFirestoreCollection <Customer>;
16  customerDoc: AngularFirestoreDocument <Customer>;
17  customers: Observable<Customer[]>;
18
19   constructor(
20    public angularFireStore: AngularFirestore
21
22  ) 
23  {}
24
25    getCustomer() {
26    this.customerCollection = this.angularFireStore.collection('customer');
27    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes => {
28      return changes.map( a => {
29        const data = a.payload.doc.data() as Customer;
30        data.id=a.payload.doc.id;
31        return data;
32      })
33
34    }))
35    return this.customers;
36  }
37
38  addCustomer(customerAdd:Customer) {
39    this.customerCollection.add(customerAdd);
40  };
41
42  updateCustomer(custcol : Customer) {
43    this.customerDoc = this.angularFireStore.doc(`customer/${custcol.id}`);
44    this.customerDoc.update(custcol);
45  }
46
47
48}
49
50 customerList: customerModel[];
51 customerDetails : customerModel;
52 customerName: any;
53 
54 addCustomer : Customer ={
55    customerNo: '',
56    customerAccountNo: '',
57    customerName: '',
58    customerAddress: '',
59    customerContactNo: '',
60    customerEmail: ''
61
62  };
63
64ngOnInit(): void {
65 this.customerService.getCustomer().subscribe( customerObservable => {
66 this.customerList = customerObservable});
67}
68
69
70add() {
71 this.addCustomer.customerName = this.customerName //(input comes from ngModel btw)
72 this.customerCollection.add(this.addCustomer);
73}
74
75update(){
76 this.customerDetails.customerName = this.customerName //(input comes from ngModel btw)
77 this.customerService.UpdateCustomer(this.customerDetails)
78}
79import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
80import { Observable} from 'rxjs'; 
81import { Customer } from '../../models/customer.model';
82
83
84@Component({
85  selector: 'app-add-client',
86  templateUrl: './add-client.component.html',
87  styleUrls: ['./add-client.component.scss']
88})
89export class AddClientComponent implements OnInit {
90
91 private customerCollection: AngularFirestoreCollection<Customer>
92 private customerDocs: AngularFirestoreDocument<Customer>
93 customers: Observable<Customer[]>
94  
95 constructor(
96    public afs: AngularFirestore
97  ) { 
98    this.customerCollection = this.afs.collection<Customer>('customer')
99    this.customers = this.customerCollection.valueChanges();
100  }
101 customerList: Customer[];
102 customerDetails: Customer;
103
104 addCustomer : Customer ={
105    customerNo: '',
106    customerAccountNo: '',
107    customerName: '',
108    customerAddress: '',
109    customerContactNo: '',
110    customerEmail: ''
111 
112  };
113
114queryCustomer() {
115    
116    this.customerCollection = this.afs.collection('customer',
117    ref => ref
118    .orderBy('customerName')
119    .startAt(this.query)
120    .endAt(this.query + "\uf8ff"));
121    this.customers = this.customerCollection.valueChanges();
122    this.customers.subscribe(
123     (data) => (this.customerList = (data)));
124  }
125
126add() {
127  this.addCustomer.customerName = this.customerName;
128  this.customerCollection.add(this.addCustomer);
129}
130
131queryCustomer() {
132    
133    this.customerCollection = this.afs.collection('customer',
134    ref => ref
135    .orderBy('customerName')
136    .startAt(this.query)
137    .endAt(this.query + "\uf8ff"));
138    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes =>{
139        return changes.map(a =>{
140        const data=a.payload.doc.data() as depositModel;
141        data.id=a.payload.doc.id;
142        return data;
143       });
144      }
145    ));
146    this.customers.subscribe(
147     (data) => (this.customerList = (data)));
148  }
149
150
151}
152
153update() {
154 
155  this.customerDocs = this.angularFirestore.doc(`jobOrders/${customerDetails.id}`);
156  this.customerDocs.Update(customerDetails);
157
158}
159
160
161onRename() {
162        if (!this.editForm.value.replaceValue) {
163            this.message = "Cannot Be Empty!";
164        } else {
165            this.firestore.collection('testCollection').doc(this.id).update({ field: this.editForm.value.replaceValue });
166            this.edit = false;
167            this.message2 = '';
168            this.single = null;
169        }
170    }
171

Example2 :

1
2Via Service:
3
4
5import { Injectable } from '@angular/core';
6import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
7import { Observable } from 'rxjs';
8import {map } from 'rxjs/operators';
9
10@Injectable({
11  providedIn: 'root'
12})
13
14export class CustomerService {
15  customerCollection: AngularFirestoreCollection <Customer>;
16  customerDoc: AngularFirestoreDocument <Customer>;
17  customers: Observable<Customer[]>;
18
19   constructor(
20    public angularFireStore: AngularFirestore
21
22  ) 
23  {}
24
25    getCustomer() {
26    this.customerCollection = this.angularFireStore.collection('customer');
27    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes => {
28      return changes.map( a => {
29        const data = a.payload.doc.data() as Customer;
30        data.id=a.payload.doc.id;
31        return data;
32      })
33
34    }))
35    return this.customers;
36  }
37
38  addCustomer(customerAdd:Customer) {
39    this.customerCollection.add(customerAdd);
40  };
41
42  updateCustomer(custcol : Customer) {
43    this.customerDoc = this.angularFireStore.doc(`customer/${custcol.id}`);
44    this.customerDoc.update(custcol);
45  }
46
47
48}
49
50 customerList: customerModel[];
51 customerDetails : customerModel;
52 customerName: any;
53 
54 addCustomer : Customer ={
55    customerNo: '',
56    customerAccountNo: '',
57    customerName: '',
58    customerAddress: '',
59    customerContactNo: '',
60    customerEmail: ''
61
62  };
63
64ngOnInit(): void {
65 this.customerService.getCustomer().subscribe( customerObservable => {
66 this.customerList = customerObservable});
67}
68
69
70add() {
71 this.addCustomer.customerName = this.customerName //(input comes from ngModel btw)
72 this.customerCollection.add(this.addCustomer);
73}
74
75update(){
76 this.customerDetails.customerName = this.customerName //(input comes from ngModel btw)
77 this.customerService.UpdateCustomer(this.customerDetails)
78}
79import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
80import { Observable} from 'rxjs'; 
81import { Customer } from '../../models/customer.model';
82
83
84@Component({
85  selector: 'app-add-client',
86  templateUrl: './add-client.component.html',
87  styleUrls: ['./add-client.component.scss']
88})
89export class AddClientComponent implements OnInit {
90
91 private customerCollection: AngularFirestoreCollection<Customer>
92 private customerDocs: AngularFirestoreDocument<Customer>
93 customers: Observable<Customer[]>
94  
95 constructor(
96    public afs: AngularFirestore
97  ) { 
98    this.customerCollection = this.afs.collection<Customer>('customer')
99    this.customers = this.customerCollection.valueChanges();
100  }
101 customerList: Customer[];
102 customerDetails: Customer;
103
104 addCustomer : Customer ={
105    customerNo: '',
106    customerAccountNo: '',
107    customerName: '',
108    customerAddress: '',
109    customerContactNo: '',
110    customerEmail: ''
111 
112  };
113
114queryCustomer() {
115    
116    this.customerCollection = this.afs.collection('customer',
117    ref => ref
118    .orderBy('customerName')
119    .startAt(this.query)
120    .endAt(this.query + "\uf8ff"));
121    this.customers = this.customerCollection.valueChanges();
122    this.customers.subscribe(
123     (data) => (this.customerList = (data)));
124  }
125
126add() {
127  this.addCustomer.customerName = this.customerName;
128  this.customerCollection.add(this.addCustomer);
129}
130
131queryCustomer() {
132    
133    this.customerCollection = this.afs.collection('customer',
134    ref => ref
135    .orderBy('customerName')
136    .startAt(this.query)
137    .endAt(this.query + "\uf8ff"));
138    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes =>{
139        return changes.map(a =>{
140        const data=a.payload.doc.data() as depositModel;
141        data.id=a.payload.doc.id;
142        return data;
143       });
144      }
145    ));
146    this.customers.subscribe(
147     (data) => (this.customerList = (data)));
148  }
149
150
151}
152
153update() {
154 
155  this.customerDocs = this.angularFirestore.doc(`jobOrders/${customerDetails.id}`);
156  this.customerDocs.Update(customerDetails);
157
158}
159
160
161onRename() {
162        if (!this.editForm.value.replaceValue) {
163            this.message = "Cannot Be Empty!";
164        } else {
165            this.firestore.collection('testCollection').doc(this.id).update({ field: this.editForm.value.replaceValue });
166            this.edit = false;
167            this.message2 = '';
168            this.single = null;
169        }
170    }
171updateCoffeeOrder(data) {
172   return
173       this.firestore
174       .collection("coffeeOrders")
175       .doc(data.payload.doc.id)
176       .set({ completed: true }, { merge: true });
177}
178

You can refer to the stackoverflow thread and video on CRUD operations.

Source https://stackoverflow.com/questions/71262617

QUESTION

How to maintain a table of all proxy models in Django?

Asked 2022-Mar-04 at 17:01

I have a model A and want to make subclasses of it.

1class A(models.Model):
2    type = models.ForeignKey(Type)
3    data = models.JSONField()
4    
5    def compute():
6            pass
7
8class B(A):
9    def compute():
10        df = self.go_get_data()
11        self.data = self.process(df)
12
13class C(A):
14    def compute():
15        df = self.go_get_other_data()
16        self.data = self.process_another_way(df)
17
18# ... other subclasses of A
19

B and C should not have their own tables, so I decided to use the proxy attirbute of Meta. However, I want there to be a table of all the implemented proxies. In particular, I want to keep a record of the name and description of each subclass. For example, for B, the name would be "B" and the description would be the docstring for B. So I made another model:

1class A(models.Model):
2    type = models.ForeignKey(Type)
3    data = models.JSONField()
4    
5    def compute():
6            pass
7
8class B(A):
9    def compute():
10        df = self.go_get_data()
11        self.data = self.process(df)
12
13class C(A):
14    def compute():
15        df = self.go_get_other_data()
16        self.data = self.process_another_way(df)
17
18# ... other subclasses of A
19class Type(models.Model):
20    # The name of the class
21    name = models.String()
22    # The docstring of the class
23    desc = models.String()
24    # A unique identifier, different from the Django ID,
25    # that allows for smoothly changing the name of the class
26    identifier = models.Int()
27

Now, I want it so when I create an A, I can only choose between the different subclasses of A. Hence the Type table should always be up-to-date. For example, if I want to unit-test the behavior of B, I'll need to use the corresponding Type instance to create an instance of B, so that Type instance already needs to be in the database.

Looking over on the Django website, I see two ways to achieve this: fixtures and data migrations. Fixtures aren't dynamic enough for my usecase, since the attributes literally come from the code. That leaves me with data migrations.

I tried writing one, that goes something like this:

1class A(models.Model):
2    type = models.ForeignKey(Type)
3    data = models.JSONField()
4    
5    def compute():
6            pass
7
8class B(A):
9    def compute():
10        df = self.go_get_data()
11        self.data = self.process(df)
12
13class C(A):
14    def compute():
15        df = self.go_get_other_data()
16        self.data = self.process_another_way(df)
17
18# ... other subclasses of A
19class Type(models.Model):
20    # The name of the class
21    name = models.String()
22    # The docstring of the class
23    desc = models.String()
24    # A unique identifier, different from the Django ID,
25    # that allows for smoothly changing the name of the class
26    identifier = models.Int()
27def update_results(apps, schema_editor):
28    A = apps.get_model("app", "A")
29    Type = apps.get_model("app", "Type")
30    subclasses = get_all_subclasses(A)
31    for cls in subclasses:
32        id = cls.get_identifier()
33        Type.objects.update_or_create(
34            identifier=id,
35            defaults=dict(name=cls.__name__, desc=cls.__desc__)
36        )
37    
38class Migration(migrations.Migration):
39
40    operations = [
41        RunPython(update_results)
42    ]
43    
44    # ... other stuff
45

The problem is, I don't see how to store the identifier within the class, so that the Django Model instance can recover it. So far, here is what I have tried:

I have tried using the fairly new __init_subclass__ construct of Python. So my code now looks like:

1class A(models.Model):
2    type = models.ForeignKey(Type)
3    data = models.JSONField()
4    
5    def compute():
6            pass
7
8class B(A):
9    def compute():
10        df = self.go_get_data()
11        self.data = self.process(df)
12
13class C(A):
14    def compute():
15        df = self.go_get_other_data()
16        self.data = self.process_another_way(df)
17
18# ... other subclasses of A
19class Type(models.Model):
20    # The name of the class
21    name = models.String()
22    # The docstring of the class
23    desc = models.String()
24    # A unique identifier, different from the Django ID,
25    # that allows for smoothly changing the name of the class
26    identifier = models.Int()
27def update_results(apps, schema_editor):
28    A = apps.get_model("app", "A")
29    Type = apps.get_model("app", "Type")
30    subclasses = get_all_subclasses(A)
31    for cls in subclasses:
32        id = cls.get_identifier()
33        Type.objects.update_or_create(
34            identifier=id,
35            defaults=dict(name=cls.__name__, desc=cls.__desc__)
36        )
37    
38class Migration(migrations.Migration):
39
40    operations = [
41        RunPython(update_results)
42    ]
43    
44    # ... other stuff
45class A:
46
47    def __init_subclass__(cls, identifier=None, **kwargs):
48        super().__init_subclass__(**kwargs)
49        if identifier is None:
50            raise ValueError()
51        cls.identifier = identifier
52        Type.objects.update_or_create(
53            identifier=identifier,
54            defaults=dict(name=cls.__name__, desc=cls.__doc__)
55        )
56    
57    # ... the rest of A
58
59# The identifier should never change, so that even if the
60# name of the class changes, we still know which subclass is referred to
61class B(A, identifier=3):
62
63    # ... the rest of B
64

But this update_or_create fails when the database is new (e.g. during unit tests), because the Type table does not exist. When I have this problem in development (we're still in early stages so deleting the DB is still sensible), I have to go comment out the update_or_create in __init_subclass__. I can then migrate and put it back in.

Of course, this solution is also not great because __init_subclass__ is run way more than necessary. Ideally this machinery would only happen at migration.

So there you have it! I hope the problem statement makes sense.

Thanks for reading this far and I look forward to hearing from you; even if you have other things to do, I wish you a good rest of your day :)

ANSWER

Answered 2022-Mar-04 at 17:01

With a little help from Django-expert friends, I solved this with the post_migrate signal. I removed the update_or_create in __init_subclass, and in project/app/apps.py I added:

1class A(models.Model):
2    type = models.ForeignKey(Type)
3    data = models.JSONField()
4    
5    def compute():
6            pass
7
8class B(A):
9    def compute():
10        df = self.go_get_data()
11        self.data = self.process(df)
12
13class C(A):
14    def compute():
15        df = self.go_get_other_data()
16        self.data = self.process_another_way(df)
17
18# ... other subclasses of A
19class Type(models.Model):
20    # The name of the class
21    name = models.String()
22    # The docstring of the class
23    desc = models.String()
24    # A unique identifier, different from the Django ID,
25    # that allows for smoothly changing the name of the class
26    identifier = models.Int()
27def update_results(apps, schema_editor):
28    A = apps.get_model("app", "A")
29    Type = apps.get_model("app", "Type")
30    subclasses = get_all_subclasses(A)
31    for cls in subclasses:
32        id = cls.get_identifier()
33        Type.objects.update_or_create(
34            identifier=id,
35            defaults=dict(name=cls.__name__, desc=cls.__desc__)
36        )
37    
38class Migration(migrations.Migration):
39
40    operations = [
41        RunPython(update_results)
42    ]
43    
44    # ... other stuff
45class A:
46
47    def __init_subclass__(cls, identifier=None, **kwargs):
48        super().__init_subclass__(**kwargs)
49        if identifier is None:
50            raise ValueError()
51        cls.identifier = identifier
52        Type.objects.update_or_create(
53            identifier=identifier,
54            defaults=dict(name=cls.__name__, desc=cls.__doc__)
55        )
56    
57    # ... the rest of A
58
59# The identifier should never change, so that even if the
60# name of the class changes, we still know which subclass is referred to
61class B(A, identifier=3):
62
63    # ... the rest of B
64from django.apps import AppConfig
65from django.db.models.signals import post_migrate
66
67
68def get_all_subclasses(cls):
69    """Get all subclasses of a class, recursively.
70
71    Used to get a list of all the implemented As.
72    """
73    all_subclasses = []
74
75    for subclass in cls.__subclasses__():
76        all_subclasses.append(subclass)
77        all_subclasses.extend(get_all_subclasses(subclass))
78
79    return all_subclasses
80
81
82def update_As(sender=None, **kwargs):
83    """Get a list of all implemented As and write them in the database.
84
85    More precisely, each model is used to instantiate a Type, which will be used to identify As.
86    """
87    from app.models import A, Type
88
89    subclasses = get_all_subclasses(A)
90    for cls in subclasses:
91        id = cls.identifier
92        Type.objects.update_or_create(identifier=id, defaults=dict(name=cls.__name__, desc=cls.__doc__))
93
94
95class MyAppConfig(AppConfig):
96    default_auto_field = "django.db.models.BigAutoField"
97    name = "app"
98
99    def ready(self):
100        post_migrate.connect(update_As, sender=self)
101

Hope this is helpful for future Django coders in need!

Source https://stackoverflow.com/questions/71338161

QUESTION

How to abandon a manual Room migration script, and fall back to destructive migration?

Asked 2022-Mar-04 at 04:22

In the app I'm working on, we had a complex manual migration that required data parsing, manual SQL commands, etc. This was to convert a List<X> column into a new linked table of X. I've previously written about the approach, but the specific commands are not especially relevant for this question.

The issue I'm encountering is ~1% of users are experiencing a crash as part of this migration. This cannot be reproduced in testing, and due to our table's size, Crashlytics cannot show any useful error:

crashlytics truncated error

Losing customer data isn't catastrophic in this context, but being stuck in the current "try migrate, crash, reopen app and repeat" loop is. As such, I want to just give up on the migration and fall back to a destructive migration if we encounter an exception.

Any ideas how this can be done? My current solution is rerunning the DB changes (but not the presumably failing data migration) inside the catch, but this feels very hacky.


Our database is defined as:

1Room.databaseBuilder(
2        context.applicationContext,
3        CreationDatabase::class.java,
4        &quot;creation_database&quot;
5    )
6    .addMigrations(MIGRATION_11_12, MIGRATION_14_15)
7    .fallbackToDestructiveMigration()
8    .build()
9

where MIGRATION_14_15 is:

1Room.databaseBuilder(
2        context.applicationContext,
3        CreationDatabase::class.java,
4        &quot;creation_database&quot;
5    )
6    .addMigrations(MIGRATION_11_12, MIGRATION_14_15)
7    .fallbackToDestructiveMigration()
8    .build()
9private val MIGRATION_14_15 = object : Migration(14, 15) {
10    override fun migrate(database: SupportSQLiteDatabase) {
11        try {
12            // database.execSQL create table etc
13        } catch (e: Exception) {
14            e.printStackTrace()
15            // Here is where I want to give up, and start the DB from scratch
16        }
17    }
18}
19

ANSWER

Answered 2022-Mar-04 at 04:22

The problem you have is that you cannot (at least easily) invoke the fall-back as that is only invoked when there is no migration.

What you could do is to mimic what fall back does (well close to what it does). That is the fall-back will delete (I think) the database file and create the database from scratch and then invoke the databases _Impl (generated java) createAllTables method.

However, you would likely have issues if you deleted the file as the database connection has been passed to the migration.

So instead you could DROP all the app's tables using the code copied from the dropAllTables method from the generated java. You could then follow this with the code from the createAllTables method.

  • These methods are in the generated java as the class that is the same as the class that is annotated with @Database suffixed with _Impl.

The gotcha, is that the exception enter image description here

(Expected .... Found ....) that you have shown is NOT within the migration but after the migration when Room is trying to build the database, so you have no control/place to do the above fall-back mimic unless this was done for all 14-15 migrations.

Perhaps what you could do is to trap the exception, present a dialog requesting the user to uninstall the app and to then re-install. This would then bypass the migration as it would be a fresh install.

Source https://stackoverflow.com/questions/71339724

QUESTION

Copy SQL Server Scheduled Jobs to Oracle Scheduler

Asked 2022-Mar-02 at 12:25

I have a requirement of migrating from SQL Server to Oracle 19C. Data migration is done and now I want to know whether there is a mechanism in Oracle to copy SQL Server scheduled job to Oracle Scheduler?

ANSWER

Answered 2022-Mar-02 at 12:25

Non, there is not. You have to understand what each work do and traduce it in the ways of Oracle do, then schedule the work with Oracle Scheduler.

Source https://stackoverflow.com/questions/71317186

QUESTION

Using SchemaCrawler API to get Weak/Implied Relationships

Asked 2022-Feb-17 at 23:47

I'm using the SchemaCrawler API in a data migration tool I'm developing. This is running on MySQL 5.6.25 with v16.16.9 of the SchemaCrawler API. Unfortunately, SC isn't finding any weak relationships in the database, even though other tools are identifying them. In the sample below, I'm looping through every table in the database and printing the weak associations, but the weak associations collection is always empty:

1for (Map.Entry&lt;String, Table&gt; entry : tableMap.entrySet()) { 
2    String tableName = entry.getKey();
3    Table sampleTable = entry.getValue();
4    Collection&lt;WeakAssociation&gt; weakAssociations = sampleTable.getWeakAssociations();
5    System.out.println(String.format(&quot;Table: %s, associations=%s&quot;, tableName, weakAssociations));
6}
7

I couldn't find any sample code relating to weak associations, so maybe I'm just using it incorrectly. Any help is appeciated.

ANSWER

Answered 2022-Feb-17 at 23:47

You need to set "weak-associations" to true in the configuration. Please take a look at WeakAssociationsTest for example code.

Sualeh Fatehi, SchemaCrawler

Source https://stackoverflow.com/questions/71159865

QUESTION

MySQL idempotent version of add column failing

Asked 2022-Feb-14 at 18:45

MySQL here. Trying to add a column to a table in idempotent fashion. In reality it will be a SQL script that gets ran as part of an application data migration, so it will be ran over and over and I want to make sure that we only run it if the column does not already exist.

My best attempt so far:

1IF NOT EXISTS (SELECT 1
2    FROM information_schema.COLUMNS 
3    WHERE 
4        TABLE_SCHEMA = 'myapp' 
5    AND TABLE_NAME = 'mytable' 
6    AND COLUMN_NAME = 'fizzbuzz')
7BEGIN 
8  alter table myapp.mytable
9    add column fizzbuzz tinyint(1) not null default false;
10END
11

yields a vague syntax error:

1IF NOT EXISTS (SELECT 1
2    FROM information_schema.COLUMNS 
3    WHERE 
4        TABLE_SCHEMA = 'myapp' 
5    AND TABLE_NAME = 'mytable' 
6    AND COLUMN_NAME = 'fizzbuzz')
7BEGIN 
8  alter table myapp.mytable
9    add column fizzbuzz tinyint(1) not null default false;
10END
11&quot;IF&quot; is not valid at this position, expecting EOF, ALTER, ANALYZE, BEGIN, BINLOG, CACHE, ...
12

Can anyone spot where my syntax is going awry?

ANSWER

Answered 2022-Feb-14 at 18:45

use:

1IF NOT EXISTS (SELECT 1
2    FROM information_schema.COLUMNS 
3    WHERE 
4        TABLE_SCHEMA = 'myapp' 
5    AND TABLE_NAME = 'mytable' 
6    AND COLUMN_NAME = 'fizzbuzz')
7BEGIN 
8  alter table myapp.mytable
9    add column fizzbuzz tinyint(1) not null default false;
10END
11&quot;IF&quot; is not valid at this position, expecting EOF, ALTER, ANALYZE, BEGIN, BINLOG, CACHE, ...
12ALTER TABLE myapp.mytable
13    ADD COLUMN IF NOT exists fizzbuzz TINYINT(1) NOT NULL DEFAULT FALSE;
14

Source https://stackoverflow.com/questions/71116469

Community Discussions contain sources that include Stack Exchange Network

Tutorials and Learning Resources in Data Migration

Tutorials and Learning Resources are not available at this moment for Data Migration

Share this Page

share link

Get latest updates on Data Migration