RethinkDB: merge two tables if one does not contains key of other - node.js

I am merging two tables
Table 1's primary key exists in table 2 but in some case there is no key foreign in table 2. Which fires error that there is no key exists.
I want to merge table with condition only if key exists;
r.table('sport').filter({sport_id:sport_id}).merge(function(doc){
return {
terminology: r.table('sport_terminology').get(doc("terminology_id"))
}
})
.run(conn, sport);
Now if sport does not contain terminology as key than it is firing error. Please give me solution for merge bypass if key does not exists

It is a bit unclear from your question what is it that you're having trouble with, since you haven't posted the exception you're getting.
I assume that for some documents, you're getting a "No attribute 'terminology_id' in object". If that's the case, simply add a default() value, e.g:
r.table('sport').filter({sport_id:sport_id}).merge(function(doc) {
return {
terminology: r.table('sport_terminology')
.get(doc("terminology_id").default(null))
}
})
If it's not the case, please post the error message.

Related

How to keep remark when update type of a column in liquibase?

I try to update type of a column using modifyDataType in a Groovy DSL. After I run liquibase update by liquibase-maven-plugin(version is 3.8.9), I found the remark of column disappeared.
here is my code:
changeSet(author: "root", id: "20201218-modify-data-type") {
modifyDataType(columnName: "description", newDataType: "text", tableName: "t_user")
rollback {
modifyDataType(columnName: "description", newDataType: "varchar(2000)", tableName: "t_user")
}
}
I can not add param "remark" in modifyDataType(), because 'remarks' is an invalid property for 'modifyDataType' changes.
The way MySQL implements their ALTER TABLE MODIFY COLUMN is as if it drops the old column and adds a new one. This loses not just remarks, but also constraints or primary keys or anything else related to the "old" column.
We've not added all those fields into modifyDataType since there is really no end to what we'd have to include in there. Instead, if you modify a datatype on mysql you need to re-set the remarks, primary keys, etc. in separate calls.
There is a warning we output for mysql about losing primary key/constraint info, but we only show it for non-varchar datatypes to keep the number of warnings down. Since it affects things like remarks which can be on varchars, it's probably worth removing that non-varchar part of the check.

Getting index of the resultset

Is there a way to get the index of the results within an aql query?
Something like
FOR user IN Users sort user.age DESC RETURN {id:user._id, order:{index?}}
If you want to enumerate the result set and store these numbers in an attribute order, then this is possible with the following AQL query:
LET sorted_ids = (
FOR user IN Users
SORT user.age DESC
RETURN user._key
)
FOR i IN 0..LENGTH(sorted_ids)-1
UPDATE sorted_ids[i] WITH { order: i+1 } IN Users
RETURN NEW
A subquery is used to sort users by age and return an array of document keys. Then a loop over a numeric range from the first to the last index of the that array is used to iterate over its elements, which gives you the desired order value (minus 1) as variable i. The current array element is a document key, which is used to update the user document with an order attribute.
Above query can be useful for a one-off computation of an order attribute. If your data changes a lot, then it will quickly become stale however, and you may want to move this to the client-side.
For a related discussion see AQL: Counter / enumerator
If I understand your question correctly - and feel free to correct me, this is what you're looking for:
FOR user IN Users
SORT user.age DESC
RETURN {
id: user._id,
order: user._key
}
The _key is the primary key in ArangoDB.
If however, you're looking for example data entered (in chronological order) then you will have to have to set the key on your inserts and/or create a date / time object and filter using that.
Edit:
Upon doing some research, I believe this link might be of use to you for AI the keys: https://www.arangodb.com/2013/03/auto-increment-values-in-arangodb/

how to skip unique constraint?

I have tried to insert many records into a table, and this table has a unique constraint, so when if one user try to add a new record with the same unique value, I get the dbUpdateException.
But I would like to know how to skipt this error and try to add the remaining records that the first user are trying to add to the table.
How can do that?
Thanks.
One approach could be to catch the DbUpdateException, and use its Entries property to remove the duplicate entities from the context.
You could then retry the save - rinse and repeat - and eventually all the non-duplicate entities will be saved.
E.g.
var duplicates = new List<MyEntity>();
...
catch(DbUpdateException ex)
{
ex.Entries.Each(e => DbContext.Entry(e).State = EntityState.Detached;
duplicates.Add(ex.Entries);
ReTrySave(); // do whatever you need todo to re-enter your saving code
}
...
// Report to user the duplicate entities
ReportToUser(duplicates);
NOTE - treat as pseudo code as I haven't attempted to compile this snippet.

SQL Azure Database / Can't Insert Record into a Table / ID not getting set during SubmitChanges

In the following instance, I have tried to simplify an issue to root components.
I've got a very simple SQL Azure database where I created a test table called Table1. Azure creates an ID field with Is Required, Is Primary Key checked. It will NOT allow to check the box Is Identity. There are a couple of other fields which are simply required.
In my VS2012 Project, I have created an LinqToSql Class which created a ProductionDataClasses1.dbml object.
I simply want to add a record to this table thru the method shown below. From what I am reading, ID would be set during the SubmitChanges() after InsertOnSubmit(NewRecord) is specified.
It does work the first time but value is set to zero. On subsequent save, I get an exception (basically it a duplicate record because ID=0 already exists).
To put this into context, I have included some sample code below. The idea is to first check if the record exists and update. If not, I want to add a record.
My question is... Do I need to manually set ID? If so, how do I set the value to an int and how to a retrieve the next value. I tried changing to a Guid but not allowed.
Here is my code sample:
public bool AddTestRecord(string someValue)
{
ProductionDataClasses1DataContext context = new ProductionDataClasses1DataContext();
try
{
var ExistingRecord = context.Table1s.SingleOrDefault(c => c.TextKey == someValue);
if (ExistingRecord == null)
{
var NewRecord = new Table1();
// NewRecord.ID = ???? ; How Do I Manually Set. It is getting set to 0 causing a duplicate value exception
NewRecord.TextKey = someValue;
NewRecord.AnotherValue = DateTime.Now.ToShortTimeString();
context.Table1s.InsertOnSubmit(NewRecord);
}
else
{
ExistingRecord.AnotherValue = DateTime.Now.TimeOfDay.ToString();
}
context.SubmitChanges();
return true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
return false;
context.SubmitChanges();
}
}
I would suggest manually running a SQL script to alter the table and make the column an identity. Look at this answer
Adding an identity to an existing column
Thanks for your reply.
I just was finally able to make this work on a new table and will try to follow along your instructions to make modifications to my real table. My code (as written above) was OK so the issue is in the SQL Azure table definition.
I found the issue is that when you create a new table in SQL Azure, it creates a table with three fields, ID, Column1, Column2. By default, ID is set as the Primary Key but none are checked as Is Identity.
To make this work, I made ID the Is Identity and unchecked PrimaryKey and Column1 the In Primary Key. Thus when a new record is saved, the ID is set and Column1 is checked to make sure it is not already in the system. I had to do this when the table was first created. Once saved, it would not allow me to change.
Afterwards, I updated my Linq To SQL class and dropped the new table in. I noted that now the AutoGenerated Value on ID and PrimaryKey on Column1 was set and my code worked.

SubSonic 3 / ActiveRecord - Easy way to compare two records?

With SubSonic 3 / ActiveRecord, is there an easy way to compare two records without having to compare each column by column. For example, I'd like a function that does something like this (without having to write a custom comparer for each table in my database):
public partial class MyTable
{
public IList<SubSonic.Schema.IColumn> Compare(MyTable m)
{
IList<SubSonic.Schema.IColumn> columnsThatDontMatch = new...;
if (this.Field1 != m.Field1)
{
columnsThatDontMatch.add(Field1_Column);
}
if (this.Field2 != m.Field2)
{
columnsThatDontMatch.add(Field2_Column);
}
...
return columnsThatDontMatch;
}
}
In the end, what I really need is a function that tests for equality between two rows, excluding the primary key columns. The pseudo-code above is a more general form of this. I believe that once I get the columns that don't match, I'll be able to check if any of the columns are primary key fields.
I've looked through Columns property without finding anything that I can use. Ideally, the solution would be something I can toss in the t4 file and generate for all my tables in the database.
The best way, if using SQL Server as your backend as this can be auto populated, is to create a derived column that has a definition that uses CHECKSUM to hash the values of "selected" columns to form a uniqueness outside of the primary key.
EDIT: if you are not using SQL Server then this hashing will need to be done in code as you save, edit the row.

Resources