I want create migration with Sequelize to rename column with camelCase to have a database with column in snake_case.
I use Sequelize to create migration and use migration.
module.exports = {
up: function(queryInterface, Sequelize) {
return queryInterface.renameColumn('my_some_table', 'totoId', 'toto_id');
},
down: function(queryInterface, Sequelize) {
//
}
};
But... I have a unique constraint on this column (totoId) and name column, named my_some_table_name_totoId_uindex, and I also have an index on this column (totoId).
How I can force renaming column who have a unique constraint and one index?
You have to drop all the constraints, rename the column and then add the constraints back. With a single constraint on totoId it would look something like this:
// 1) drop constraint
queryInterface.removeConstraint('my_some_table', 'my_constraint');
// 2) rename column
queryInterface.renameColumn('my_some_table', 'totoId', 'toto_id');
// 3) add constraint back
queryInterface.addConstraint('my_some_table', ['toto_id'], {
type: 'unique',
name: 'my_constraint'
});
Remember that migrations should be atomic operations. So you should create 3 migrations in that order. Or even better, as #Santilli pointed out in the comments, you could create a transaction.
This will prevent from any change to be applied if one of the queries fails:
return queryInterface.sequelize.transaction(async (transaction) => {
await queryInterface.removeConstraint("my_some_table", "my_constraint", {
transaction,
});
await queryInterface.renameColumn("my_some_table", "totoId", "toto_id", {
transaction,
});
await queryInterface.addConstraint("my_some_table", ["toto_id"], {
type: "unique",
name: "my_constraint",
transaction,
});
});
Also, remember to create a transaction to revert the changes in the down function.
Related
I want to try and create a new record, but if that fails, simply update (increment) a value in that record
await databaseService.knex('myTable')
.insert({
id: id1,
value: 0
})
.onConflict(['id1'])
.increment({
value: 1
});
Unfortunately it seems you cannot chain .increment after onConflict. I am wondering if there is a way I can do this with knex or do I need to drop into raw SQL?
Thanks
With on conflict for update part merge should be used https://knexjs.org/#Builder-merge
something like this might work:
await databaseService.knex('myTable')
.insert({
id: id1,
value: 0
})
.onConflict(['id'])
.merge({
value: knex.raw("?? + ?", ["value", 1])
});
https://runkit.com/embed/krdgetjij9xh
I have this problem right now that I don't know how to fix honestly. I spent hours on this already and cannot find the solution. I am using MS-SQL on Azure.
The way I have set up my entities is the following:
Customer and Visits: OneToMany (Primary)
Visits and Customers: ManyToOne (Inverse)
I am soft-deleting my customers, so that the information for the visits can be retrieved regardless of whether or not the user wants to see the customer data specifically. The data is still getting resolved correctly using the relationship. That's also why I don't want to use "Cascade DELETE" here.
However, since I want to delete visits completely (not soft-deleting like the customers) I am facing issues probably regarding foreign key constraints (not sure, because I don't get any error output from TypeORM). The DeleteResult.affected property however returns 0, which is what I see in my DataGrip queries as well, where I check the actual table data.
Whats important as well is that I am able to manually delete the row using a simple SQL statement like the following:
DELETE FROM visits
WHERE uuid = 'f0ea300d-...-656a'
My entities are set up like this (left unimportant information out):
#Entity({ name: 'customers' })
export class Customer {
#PrimaryColumn()
uuid: string
#OneToMany(() => Visit, (visit) => visit.customer)
visits?: Visit[]
}
#Entity({ name: 'visits' })
export class Visit {
#PrimaryColumn()
uuid: string
#ManyToOne(() => Customer, (customer) => customer.visits)
customer: Customer
}
My GraphQL resolver:
#Mutation(() => Boolean)
async deleteVisitsByUuid(
#Arg('uuid') uuid: string,
#Ctx() { conn }: AppContext,
): Promise<boolean> {
const repo = conn.getRepository(Customer)
const result = await repo.delete(uuid)
const affected = result.affected
if (affected === undefined || affected == null) {
return false
} else {
return affected > 0
}
}
The problem was conn.getRepository(Customer). I have replaced it with conn.getRepository(Visit).
I'm strugling with something that maybe is pretty simple.
I'm using a postgrès SQL with sequelize and typescript.
what I'm trying to do is to create two things and one as Reference on the other but if the creation of one fail then I don't want to commit anythigs.
This is my code where I'm trying to create someone and assign hime some shoes.
CREATE TABLE User
(
id BIGSERIAL PRIMARY KEY,
firstname TEXT,
lastName TEXT
);
CREATE TABLE Shoes
(
id BIGSERIAL PRIMARY KEY,
size INTEGER NOT NULL,
idUser BIGINT REFERENCES User(id) NOT NULL
);
async function operations() {
const t = await sequelize.transaction();
try {
await User.create({
firstName: 'Bart',
lastName: 'Simpson'
}, { transaction: t });
await Shoes.create({
idUser: // here I want the id of my futur new creation (bart simpson)
size: 43
}, { transaction: t });
await t.commit();
} catch (error) {
await t.rollback();
}
}
operations.then(() => {/*do something*/})
the thing is, I don't know how to get the futur Id of my new user and if I'm putting something hard like 1 if the database is empty or if I get the latest id user and I'm adding 1 then I get an error violates foreign key constraint.
I think it's because the user isn't existing in the database but it exist in the transaction.
If someone could help me :)
I fact sending a transaction in a get can also return the value that will be created in the transaction so just need to use get and send the exact same transaction inside the methode
As per this link:
Supported Operations on DynamoDB
"You can query only tables that have a composite primary key (partition key and sort key)."
This doesn't seem correct though. I have a table in DynamoDB called 'users' which has a Primary Key that consists of only one attribute 'username'.
And I'm able to query this table just fine in NodeJS using only a 'KeyConditionExpression' on the attribute 'username'. Please see below:
var getUserByUsername = function (username, callback) {
var dynamodbDoc = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "users",
KeyConditionExpression: "username = :username",
ExpressionAttributeValues: {
":username": username
}
};
dynamodbDoc.query(params, function (err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
callback(err, null);
} else {
console.log("DynamoDB Query succeeded.");
callback(null, data);
}
});
}
This code works just fine. So I'm wondering if the documentation is incorrect or am I missing something?
The documentation is correct.
"Partition Key and Sort Key – A composite primary key, composed of two attributes. The first attribute is the partition key, and the second attribute is the sort key. DynamoDB uses the partition key value as input to an internal hash function"
http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DataModel.html
If a table doesn't have a sort key (range attribute), then the composite key is built from the hash key only. One of the results of that is that items won't be sorted as you like (items are sorted by sort key)
with CouchDB is possible do queries "like" SQL. http://guide.couchdb.org/draft/cookbook.html says that
How you would do this in SQL:
SELECT field FROM table WHERE value="searchterm"
How you can do this in CouchDB:
Use case: get a result (which can be a record or set of records) associated with a key ("searchterm").
To look something up quickly, regardless of the storage mechanism, an index is needed. An index is a data structure optimized for quick search and retrieval. CouchDB’s map result is stored in such an index, which happens to be a B+ tree.
To look up a value by "searchterm", we need to put all values into the key of a view. All we need is a simple map function:
function(doc) {
if(doc.value) {
emit(doc.value, null);
}
}
This creates a list of documents that have a value field sorted by the data in the value field. To find all the records that match "searchterm", we query the view and specify the search term as a query parameter:
/database/_design/application/_view/viewname?key="searchterm"
how can I do this with PouchDB? the API provide methods to create temp view, but how I can personalize the get request with key="searchterm"?
You just add your attribute settings to the options object:
var searchterm = "boop";
db.query({map: function(doc) {
if(doc.value) {
emit(doc.value, null);
}
}, { key: searchterm }, function(err, res) { ... });
see http://pouchdb.com/api.html#query_database for more info
using regex
import PouchDB from 'pouchdb';
import PouchDBFind from 'pouchdb-find';
...
PouchDB.plugin(PouchDBFind)
const db = new PouchDB(dbName);
db.createIndex({index: {fields: ['description']}})
....
const {docs, warning} = await db.find({selector: { description: { $regex: /OVO/}}})